Как заставить мой JComponent соответствовать JFrame.pack и менеджерам по расположению? - PullRequest
2 голосов
/ 31 августа 2011

Я сделал 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 для различных настроек:

Простой mainFrame.pack (): mainFrame.pack()

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

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

Наиболее близким к тому, чего я намерен достичь, является mainFrame.setSize (500, 500), хотя, поскольку я планирую добавить еще несколько компонентов, яожидать, что это будет хрупким.Как вы видите, в двух других, кнопка «Operate» перекрывается с компонентом ColorSample - как будто она не соответствует установленному мною менеджеру раскладки.А потом посмотрим, как упаковать срезы компонента ColorSample.Любые советы о том, как мне добиться желаемого эффекта?

Ответы [ 2 ]

4 голосов
/ 31 августа 2011

Менеджеры LayoutManager свободны в размерах / расположении компонентов по своему усмотрению, компоненты не могут их форсировать, а только дают подсказки в своих методах getXXSize (XX == min / pref / max).Таким образом, лучшее, что может сделать реализация компонента, - это

  • реализовать все getXXSize и вернуть размер, который им идеально нужен* только фрагмент
    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();
         }
    }
    
4 голосов
/ 31 августа 2011

pack() использует getPreferredSize() вашего компонента. Так что просто верните желаемый размер вашего прямоугольника, и размер будет использоваться в LayoutManager.

...