2016-09-24 54 views
0

我檢查了幾個小時的代碼,但是矩形沒有顯示,誰能告訴我,爲什麼它沒有顯示?:爲什麼矩形不顯示?

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.event.KeyEvent; 
import java.io.File; 
import java.io.IOException; 

import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 

public class Main { 

    public static void main(String[] args) { 

     JFrame frame = new JFrame(); 
     int resx = 700,resy = 500; 
     frame.setSize(resx,resy); 
     frame.setLocationRelativeTo(null); 
     frame.setTitle("Game"); 
     frame.setResizable(false); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLayout(new FlowLayout()); 
     try { 
      frame.setContentPane(new JLabel(new ImageIcon(ImageIO.read(new File("C:\\Users\\ivans\\Pictures\\Cookies.png"))))); 
     } catch (IOException e) { 
     } 
     frame.repaint(); 
     frame.setLayout(new FlowLayout()); 
     frame.add(new JPanel(){ 
      @Override 
      public void paintComponent(Graphics g){ 
       super.paintComponent(g); 
       g.setColor(Color.WHITE); 
       g.fillRect(50,50,450,650); 
      } 
     }, BorderLayout.CENTER); 
     frame.repaint(); 
     frame.setVisible(true); 
    } 

} 

每次我嘗試激活的背景下,矩形被顯示,並每次激活矩形時,都不顯示背景。請幫忙!

+0

你確定你的try {...}正文執行成功嗎?有空的catch {}部分是一個非常糟糕的做法 –

+0

我應該在「Except」服務中加入什麼? – user3150362

+0

您應該打印堆棧跟蹤並結束程序。如果在圖像中讀取引發異常,您不會希望它運行。 –

回答

1

您正在將JFrame的contentPane設置爲JLabel,這是一個不使用佈局的容器,因此向其添加組件將不允許顯示該組件,除非您完全指定該組件的大小和位置,即其組件界限。這是我避免爲contentPanes使用JLabels的一個原因(同時它不會根據它所包含的組件設置它的首選大小),而是通常更喜歡在後臺JPanel的paintComponent方法中執行我的繪圖。

方建議:

  • 你太多的事情中的主要方法 - 除非這個方案是不是比示範的目的以外的任何其他
  • 您設置Jframe的原來的contentPane(一個JPanel)到FlowLayout,但是要明白,一旦你改變了contentPane,這就沒有意義了。
  • 儘管您認爲contentPane使用了FlowLayout,但您正試圖將圖形JPanel添加到BorderLayout位置,這是無意義的。
  • 你有一個空的catch塊,幾乎從不應該完成的事情。
  • 獲取您的圖像作爲資源,而不是文件。
  • 避免使用絕對文件路徑並優先使用資源的相對路徑。
  • 如果可以避免,請不要設置尺寸。
  • 避免所謂的「幻數」,例如g.fillRect(50,50,450,650);,因爲這會使您的代碼難以調試和增強。

例如,像:

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.net.URL; 
import javax.imageio.ImageIO; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class ShowRectangle extends JPanel { 
    private static final int RECT_X = 50; 
    private static final int RECT_Y = RECT_X; 
    private static final int RECT_W = 200; 
    private static final int RECT_H = 200; 
    private static final String URL_SPEC = "https://duke.kenai.com/guitar/DukeAsKeith-daylightSmall.png"; 
    private BufferedImage img; 

    public ShowRectangle(BufferedImage img) { 
     this.img = img; 
    } 

    // have same JPanel draw image and graphic element 
    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if (img != null) { 
      g.drawImage(img, 0, 0, this); 
     } 

     // avoid magic numbers 
     // g.fillRect(50,50,450,650); 
     g.fillRect(RECT_X, RECT_Y, RECT_W, RECT_H); 
    } 

    // Size the JPanel to the image size 
    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet() || img == null) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(img.getWidth(), img.getHeight()); 
    } 

    private static void createAndShowGui(BufferedImage image) { 
     ShowRectangle mainPanel = new ShowRectangle(image); 

     JFrame frame = new JFrame("ShowRectangle"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 

     try { 
      URL imageUrl = new URL(URL_SPEC); 
      BufferedImage img = ImageIO.read(imageUrl); 
      SwingUtilities.invokeLater(() -> createAndShowGui(img)); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      System.exit(-1); 
     } 
    } 
} 

如果您避免使用例如「神奇」數字,很容易使黑色矩形可拖動的,因爲它現在是由變量值可以得出,值您可以更改MouseAdapter(MouseListener和MouseMotionListener組合)的內部。例如:

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.net.URL; 

import javax.imageio.ImageIO; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class ShowRectangle extends JPanel { 
    private static final int RECT_X = 50; 
    private static final int RECT_Y = RECT_X; 
    private static final int RECT_W = 200; 
    private static final int RECT_H = 200; 
    private static final String URL_SPEC = "https://duke.kenai.com/guitar/DukeAsKeith-daylightSmall.png"; 
    private int rectX = RECT_X; 
    private int rectY = RECT_Y; 
    private BufferedImage img; 

    public ShowRectangle(BufferedImage img) { 
     this.img = img; 
     MouseAdapter myMouse = new MyMouse(); 
     addMouseListener(myMouse); 
     addMouseMotionListener(myMouse); 
    } 

    // have same JPanel draw image and graphic element 
    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if (img != null) { 
      g.drawImage(img, 0, 0, this); 
     } 

     // avoid magic numbers 
     // g.fillRect(50,50,450,650); 
     g.fillRect(rectX, rectY, RECT_W, RECT_H); 
    } 

    // Size the JPanel to the image size 
    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet() || img == null) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(img.getWidth(), img.getHeight()); 
    } 

    private class MyMouse extends MouseAdapter { 
     private Point p1; 
     private Point rectP = null; 

     @Override 
     public void mousePressed(MouseEvent e) { 
      p1 = e.getPoint(); 
      if (new Rectangle(rectX, rectY, RECT_W, RECT_H).contains(p1)) { 
       rectP = new Point(rectX, rectY); 
      } 
     } 

     @Override 
     public void mouseDragged(MouseEvent e) { 
      moveRect(e.getPoint()); 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
      moveRect(e.getPoint()); 
      rectP = null; 
     } 

     private void moveRect(Point p2) { 
      if (rectP == null) { 
       return; 
      } 
      rectX = rectP.x + p2.x - p1.x; 
      rectY = rectP.y + p2.y - p1.y; 
      repaint(); 
     } 

    } 

    private static void createAndShowGui(BufferedImage image) { 
     ShowRectangle mainPanel = new ShowRectangle(image); 

     JFrame frame = new JFrame("ShowRectangle"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 

     try { 
      URL imageUrl = new URL(URL_SPEC); 
      BufferedImage img = ImageIO.read(imageUrl); 
      SwingUtilities.invokeLater(() -> createAndShowGui(img)); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      System.exit(-1); 
     } 
    } 
} 
+0

謝謝你的答案,但是如何將佈局添加到JLabel? – user3150362

+0

@ user3150362:在我看來,你沒有。我會使用背景JPanel。掛上..... –

+0

@ user3150362:查看上面的例子,我的意思是\ –

0

它在那裏只是它出界,因此不可見。

取代這兩條線,並檢查

g.setColor(Color.BLACK); 
g.fillRect(0,0,250,250); 

試試這個,

@Override 
      public void paintComponent(Graphics g){ 
       super.paintComponent(g); 
       Rectangle clipBounds = g.getClipBounds(); 
           System.out.println(clipBounds.getX() +" "+ clipBounds.getY() + " "+ clipBounds.getHeight() + " " + clipBounds.getWidth()); 

       g.setColor(Color.BLACK); 
       g.fillRect(0,0,450,450); 
      } 

您將獲得0.0 0.0 10.0 10。0 作爲輸出意思填充reactangle容器由0,0開始直到10,10,因此它被未示出

更改佈局GridLayout的()將解決問題,

frame.setLayout(new GridLayout()); 
     frame.add(new JPanel(new GridLayout()){ 
      /** 
      * 
      */ 
      private static final long serialVersionUID = 1L; 

      @Override 
      public void paintComponent(Graphics g){ 
       super.paintComponent(g); 
       Rectangle clipBounds = g.getClipBounds(); 
       System.out.println(clipBounds.getX() +" "+ clipBounds.getY() + " "+ clipBounds.getHeight() + " " + clipBounds.getWidth()); 
       g.setColor(Color.BLACK); 
            g.fillRect(frame.getWidth()/2,0,frame.getWidth(),frame.getWidth()); 

      } 
     }, BorderLayout.CENTER); 

作爲每DOC,

空隙java.awt.Graphics.fillRect(INT的x,INT Y,INT寬度,INT高度)

填充指定的矩形。矩形的左右邊緣位於x和x +寬度-1處。頂部和底部邊緣位於y和y +高度-1處。所得矩形覆蓋寬度像素寬高像素高的區域。矩形使用圖形上下文的當前顏色填充。 參數: x要填充矩形的x座標。 y要填充矩形的y座標。 寬度將被填充的矩形的寬度。 高度矩形的高度被填充。

所以這就是問題

+0

謝謝!雖然我有問題,但它爲什麼會顯示爲一個小的黑色方塊,而不是佔用1/2的jframe? – user3150362

+0

這是問題,圖片現在不顯示 – user3150362