如何使我的 JComponent 符合 JFrame.pack 和布局管理器?

发布于 2024-12-02 09:11:00 字数 2737 浏览 0 评论 0原文

我制作了一个显示指定颜色的矩形的 JComponent。 (还没有找到任何其他方法来达到这种效果)。问题是,它没有按预期遵循 JFrame.pack() 和布局管理器。

代码:

import java.awt.*;
import javax.swing.*;

public class FooRunnable implements Runnable{

private class ColorSample extends JComponent{

    private Color sampleColor;
    private int width, height;

    public ColorSample(int rgb, int w, int h){
        sampleColor = new Color(rgb);
        width = w;
        height = h;
    }

    public Dimension getSize(){
        return new Dimension(width, height);
    }

    public int getWidth(){
        return width;
    }

    public int getHeight(){
        return height;
    }

    public boolean isDisplayable(){
        return true;
    }

    public void paintComponent(Graphics g){
        g.setColor(sampleColor);
        g.fillRect(0, 0, width, height);
    }

}

public void run(){
    JFrame mainFrame = new JFrame();
    //mainFrame.setSize(500, 300);
    Container mainContent = mainFrame.getContentPane();
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    mainContent.setLayout(new BoxLayout(mainContent, BoxLayout.PAGE_AXIS));

    JPanel specifyFilePanel = new JPanel();
    specifyFilePanel.setLayout(new BoxLayout(specifyFilePanel, BoxLayout.LINE_AXIS));
    JLabel filenameLabel = new JLabel("File:       ");
    JButton browseButton = new JButton("Browse...");
    specifyFilePanel.add(Box.createHorizontalStrut(8));
    specifyFilePanel.add(filenameLabel);
    specifyFilePanel.add(browseButton);
    specifyFilePanel.add(Box.createHorizontalStrut(8));

    JPanel colorStatusPanel = new JPanel();
    colorStatusPanel.setLayout(new BoxLayout(colorStatusPanel, BoxLayout.Y_AXIS));
    JLabel statusLabel = new JLabel("");
    JButton roll = new JButton("Operate");
    colorStatusPanel.add(new ColorSample(Color.red.getRGB(), 50, 100));
    colorStatusPanel.add(statusLabel);
    colorStatusPanel.add(roll);

    mainContent.add(Box.createVerticalStrut(5));
    mainContent.add(specifyFilePanel);
    mainContent.add(Box.createVerticalStrut(10));
    mainContent.add(colorStatusPanel);
    mainContent.add(new JPanel());
    mainFrame.pack();
    mainFrame.setVisible(true);
}

}

我尝试在包和明确指定框架的大小之间进行试验。以下是我的 GUI 在各种设置下的默认外观:

Plain mainFrame.pack(): mainFrame.pack()

mainFrame.setSize(500, 500): 在此处输入图像描述

mainFrame.setSize(500, 300): mainFrame.setSize(500, 300)

最接近我想要实现的是 mainFrame.setSize(500, 500) 虽然,由于我计划添加更多组件,我预计它会很脆弱。正如您所看到的,在另外两个中,“操作”按钮与 ColorSample 组件重叠,就像它不遵循我设置的布局管理器一样。然后看看 ColorSample 组件是如何打包剪切的。关于如何达到我想要的效果有什么建议吗?

I made a JComponent that displays a rectangle of a specified color. (Haven't found any other way to achieve this effect). Problem is, it doesn't follow JFrame.pack() and Layout Managers as expected.

Code:

import java.awt.*;
import javax.swing.*;

public class FooRunnable implements Runnable{

private class ColorSample extends JComponent{

    private Color sampleColor;
    private int width, height;

    public ColorSample(int rgb, int w, int h){
        sampleColor = new Color(rgb);
        width = w;
        height = h;
    }

    public Dimension getSize(){
        return new Dimension(width, height);
    }

    public int getWidth(){
        return width;
    }

    public int getHeight(){
        return height;
    }

    public boolean isDisplayable(){
        return true;
    }

    public void paintComponent(Graphics g){
        g.setColor(sampleColor);
        g.fillRect(0, 0, width, height);
    }

}

public void run(){
    JFrame mainFrame = new JFrame();
    //mainFrame.setSize(500, 300);
    Container mainContent = mainFrame.getContentPane();
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    mainContent.setLayout(new BoxLayout(mainContent, BoxLayout.PAGE_AXIS));

    JPanel specifyFilePanel = new JPanel();
    specifyFilePanel.setLayout(new BoxLayout(specifyFilePanel, BoxLayout.LINE_AXIS));
    JLabel filenameLabel = new JLabel("File:       ");
    JButton browseButton = new JButton("Browse...");
    specifyFilePanel.add(Box.createHorizontalStrut(8));
    specifyFilePanel.add(filenameLabel);
    specifyFilePanel.add(browseButton);
    specifyFilePanel.add(Box.createHorizontalStrut(8));

    JPanel colorStatusPanel = new JPanel();
    colorStatusPanel.setLayout(new BoxLayout(colorStatusPanel, BoxLayout.Y_AXIS));
    JLabel statusLabel = new JLabel("");
    JButton roll = new JButton("Operate");
    colorStatusPanel.add(new ColorSample(Color.red.getRGB(), 50, 100));
    colorStatusPanel.add(statusLabel);
    colorStatusPanel.add(roll);

    mainContent.add(Box.createVerticalStrut(5));
    mainContent.add(specifyFilePanel);
    mainContent.add(Box.createVerticalStrut(10));
    mainContent.add(colorStatusPanel);
    mainContent.add(new JPanel());
    mainFrame.pack();
    mainFrame.setVisible(true);
}

}

I tried experimenting between pack and explicitly specifying the frame's size. Here are the default appearances of my GUI on various settings:

Plain mainFrame.pack():
mainFrame.pack()

mainFrame.setSize(500, 500):
enter image description here

mainFrame.setSize(500, 300):
mainFrame.setSize(500, 300)

The closest to what I intend to achieve is mainFrame.setSize(500, 500) although, as I plan to add a few more components, I expect it will be fragile. As you see, in the other two, the "Operate" button overlaps with the ColorSample Component---like it's not following the Layout Manager I set. And then see how pack cuts of the ColorSample Component. Any tips on how I can achieve the effect I want?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅紫色的梦幻 2024-12-09 09:11:00

LayoutManager 可以自由地调整组件的大小/位置,因为它们认为合适,组件不能强制它们,而只能在其 getXXSize (XX == min/pref/max) 方法中给出提示。因此,组件实现所能做的最好的事情就是

  • 实现所有 getXXSize 并返回他们理想想要的大小
  • 实现 PaintComponent 来处理

仅片段的不同大小

public class MyBox extends JComponent {
     Dimension boxSize;

     public void setBoxSize(Dimension box) {
         this.boxSize = new Dimension(box);
         ...   
     } 

     @Override
     public void paintComponent(Graphics g) {
         super.paintComponent(g);
         // position the box in the actual size
         // and paint it 
     }

     @Override
     public Dimension getPreferredSize() {
         return getBoxSize();
     }
     @Override // same for min/max
     public Dimension getM...Size( {
         return getBoxSize();
     }
}

LayoutManagers are free to size/position components as they deem appropriate, components cannot force them but only give hints in their getXXSize (XX == min/pref/max) methods. So the best a component implementation can do is

  • implement all getXXSize and return the size they ideally want
  • implement paintComponent to cope with a differing size

a snippet only

public class MyBox extends JComponent {
     Dimension boxSize;

     public void setBoxSize(Dimension box) {
         this.boxSize = new Dimension(box);
         ...   
     } 

     @Override
     public void paintComponent(Graphics g) {
         super.paintComponent(g);
         // position the box in the actual size
         // and paint it 
     }

     @Override
     public Dimension getPreferredSize() {
         return getBoxSize();
     }
     @Override // same for min/max
     public Dimension getM...Size( {
         return getBoxSize();
     }
}
奶茶白久 2024-12-09 09:11:00

pack() 使用组件的 getPreferredSize()。因此,只需返回所需的矩形大小,该大小将在 LayoutManager 中使用。

pack() uses getPreferredSize() of your component. So just return desired size of your rectangle and the size will be used in LayoutManager.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文