我有一个 JFrame 并将 LayoutManager 设置为 BorderLayout 然后继续添加我的 JLabel 和图像。但是,当我调整框架的大小时,JLabel 不会调整大小。我还没有在 North、S、E 等中添加任何组件。我希望简单地让标签内的图像填满整个框架,让我的菜单保持完整。
问问题
7557 次
2 回答
10
如果这看起来很自大,请原谅我,但我没有其他事情可做。
我做了一个快速的样本
看到图像周围的红线,那是JLabel
的边界。如您所见,标签已重新调整大小以填充整个区域。
这是我用来生成示例的代码
public class LayoutFrame extends JFrame {
public LayoutFrame() throws HeadlessException {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Image image = null;
URL url = getClass().getResource("/layout/issue78.jpg");
try {
image = ImageIO.read(url);
} catch (IOException ex) {
ex.printStackTrace();
}
JLabel label = new JLabel(new ImageIcon(image));
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
label.setBorder(new LineBorder(Color.RED, 4));
setLayout(new BorderLayout());
add(label);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
LayoutFrame frame = new LayoutFrame();
frame.setSize(200, 200);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
}
}
显然,您需要提供自己的图像;)。
不要忘记,标签不会为您缩放内容,如果这是您的目标,您需要实现自己的组件来实现这一目标。
如果您仍然遇到问题,我建议(在没有进一步证据的情况下)您的标签可能不在您认为的容器中,或者容器布局管理器不是您认为的那样。
更新
我不知道您为什么会遇到组件丢失或菜单问题的问题。混合重量和重量轻的成分?
带有菜单栏的示例
在仔细阅读您的问题后,我设计了一个简单的调整图像窗格大小的示例。为了速度,我依赖于我的库,但是用你自己的代码代替我的调用应该相当容易
public class ImagePane extends JPanel {
protected static final Object RESIZE_LOCK = new Object();
private BufferedImage image;
private BufferedImage scaledImage;
private Timer resizeTimer;
public ImagePane() {
URL url = getClass().getResource("/layout/issue78.jpg");
try {
image = ImageIO.read(url);
} catch (IOException ex) {
ex.printStackTrace();
}
resizeTimer = new Timer(250, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// Simple thread factory to start a slightly lower
// priority thread.
CoreThreadFactory.getUIInstance().execute(new ResizeTask());
}
});
resizeTimer.setCoalesce(true);
resizeTimer.setRepeats(false);
}
@Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
resizeTimer.restart();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
if (scaledImage != null) {
// This simply returns a rectangle that takes into consideration
//the containers insets
Rectangle safeBounds = UIUtilities.getSafeBounds(this);
System.out.println("scaledImage = " + scaledImage.getWidth() + "x" + scaledImage.getWidth());
int x = ((safeBounds.width - scaledImage.getWidth()) / 2) + safeBounds.x;
int y = ((safeBounds.height - scaledImage.getHeight()) / 2) + safeBounds.y;
g2d.drawImage(scaledImage, x, y, this);
}
}
protected class ResizeTask implements Runnable {
@Override
public void run() {
synchronized (RESIZE_LOCK) {
if (image != null) {
int width = getWidth();
int height = getHeight();
System.out.println("width = " + width);
System.out.println("height = " + height);
// A simple divide and conquer resize implementation
// this will scale the image so that it will fit within
// the supplied bounds
scaledImage = ImageUtilities.getScaledInstanceToFit(image, new Dimension(width, height), ImageUtilities.RenderQuality.High);
System.out.println("scaledImage = " + scaledImage.getWidth() + "x" + scaledImage.getWidth());
repaint(); // this is one of the few thread safe calls
}
}
}
}
}
于 2012-07-28T05:13:29.207 回答
1
最好的选择是继承 ImageIcon 并覆盖它的 paintIcon 方法以简单地使用 Graphics.paint(x, y, width, height ...) 绘制图像。
于 2012-07-28T08:39:23.557 回答