Вы устанавливаете область содержимого JFrame в JLabel, контейнер, который не использует макет, и поэтому добавление компонента к нему не позволит отображать этот компонент, если вы не полностью укажете размер и положение этого компонента, то есть его границы. Это одна из причин, почему я избегаю использования JLabels для contentPanes (также, что он не будет устанавливать свой предпочтительный размер на основе компонентов, которые он содержит), и вместо этого в целом предпочитает делать мой рисунок в фоновом методе paintanomponent JPanel.
Боковых рекомендации:
- Вы слишком много происходите в основном методе - если эта программа не является ни для чего, кроме демонстрационных целей
- Вы установили оригинальный ContentPane фрейма (A 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);
}
}
}
Вы уверены, что ваша попытка {...} выполняется успешно? с пустым разделом catch {} очень плохой практикой –
Что я должен поставить в «За исключением» Serction? – user3150362
Вы должны распечатать трассировку стека и завершить программу. Вы не захотите его запускать, если чтение в изображении вызывает исключение. –