您正在將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);
}
}
}
你確定你的try {...}正文執行成功嗎?有空的catch {}部分是一個非常糟糕的做法 –
我應該在「Except」服務中加入什麼? – user3150362
您應該打印堆棧跟蹤並結束程序。如果在圖像中讀取引發異常,您不會希望它運行。 –