【问题标题】:Align all gridbaglayout elements对齐所有 gridbaglayout 元素
【发布时间】:2011-12-14 16:09:44
【问题描述】:

我想用 Swing 在 Java 中制作一个类似 Firefox 的选项对话框。

我现在尝试将我的所有元素对齐在窗口的北边。我用第一个元素制作了它,但是下一个元素垂直填充了房间并且没有对齐。
为此,我正在使用 GridBagLayout。

代码如下:

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;


public class Background {  

    private Border headBorder = BorderFactory.createEmptyBorder(15, 8, 10, 8);
    private GridBagConstraints headPaneConstrain;
    private JPanel headPane;


    public Background() {

        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame dialog = new JFrame();

                //headPane
                dialog.add(headPane());

                //2 elements
                createSetting("test");
                createSetting("test2");

                //dialog settings
                dialog.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                dialog.setSize(500,500);
                dialog.setVisible(true);                
            }
        });


    }

    private JPanel createSetting(String name) {
        JPanel panel = new JPanel();
        panel.setBorder(BorderFactory.createTitledBorder(name));
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        headPane.add(panel,headPaneConstrain);
        return panel;
    }

    private JPanel headPane(){
      //Constrain
        headPaneConstrain = new GridBagConstraints();
        headPaneConstrain.fill = GridBagConstraints.HORIZONTAL;
        headPaneConstrain.anchor = GridBagConstraints.NORTH;
        headPaneConstrain.weightx = 1.0;
        headPaneConstrain.weighty = 1.0;
        headPaneConstrain.gridx=0;

        //HeadPane
        headPane = new JPanel();
        headPane.setBorder(headBorder);
        headPane.setLayout(new GridBagLayout());
        return headPane;
    }


    public static void main(String[] args) {  
       new Background();  
    }  

}  

感谢您的帮助

【问题讨论】:

  • 你在说什么 Firefox 选项对话框?从您的示例中,我看不到任何类似于我在 Firefox 7 上看到的选项对话框。您能否发布您想要的屏幕截图?

标签: java swing gridbaglayout


【解决方案1】:

这个可以帮到你

import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class ExpandingPanels extends MouseAdapter {

    private ActionPanel[] aps;
    private JPanel[] panels;

    public ExpandingPanels() {
        assembleActionPanels();
        assemblePanels();
    }

    @Override
    public void mousePressed(MouseEvent e) {
        ActionPanel ap = (ActionPanel) e.getSource();
        if (ap.target.contains(e.getPoint())) {
            ap.toggleSelection();
            togglePanelVisibility(ap);
        }
    }

    private void togglePanelVisibility(ActionPanel ap) {
        int index = getPanelIndex(ap);
        if (panels[index].isShowing()) {
            panels[index].setVisible(false);
        } else {
            panels[index].setVisible(true);
        }
        ap.getParent().validate();
    }

    private int getPanelIndex(ActionPanel ap) {
        for (int j = 0; j < aps.length; j++) {
            if (ap == aps[j]) {
                return j;
            }
        }
        return -1;
    }

    private void assembleActionPanels() {
        String[] ids = {"level 1", "level 2", "level 3", "level 4"};
        aps = new ActionPanel[ids.length];
        for (int j = 0; j < aps.length; j++) {
            aps[j] = new ActionPanel(ids[j], this);
        }
    }

    private void assemblePanels() {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(2, 1, 2, 1);
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        JPanel p1 = new JPanel(new GridBagLayout());
        gbc.gridwidth = GridBagConstraints.RELATIVE;
        p1.add(new JButton("button 1"), gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        p1.add(new JButton("button 2"), gbc);
        gbc.gridwidth = GridBagConstraints.RELATIVE;
        p1.add(new JButton("button 3"), gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        p1.add(new JButton("button 4"), gbc);

        JPanel p2 = new JPanel(new GridBagLayout());
        gbc.gridwidth = 1;
        gbc.anchor = GridBagConstraints.EAST;
        p2.add(new JLabel("enter"), gbc);
        gbc.anchor = GridBagConstraints.WEST;
        p2.add(new JTextField(8), gbc);
        gbc.anchor = GridBagConstraints.CENTER;
        p2.add(new JButton("button 1"), gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        p2.add(new JButton("button 2"), gbc);

        JPanel p3 = new JPanel(new BorderLayout());
        JTextArea textArea = new JTextArea(8, 12);
        textArea.setLineWrap(true);
        p3.add(new JScrollPane(textArea));

        JPanel p4 = new JPanel(new GridBagLayout());
        addComponents(new JLabel("label 1"), new JTextField(12), p4, gbc);
        addComponents(new JLabel("label 2"), new JTextField(16), p4, gbc);
        gbc.gridwidth = 2;
        gbc.gridy = 2;
        p4.add(new JSlider(), gbc);
        gbc.gridy++;
        JPanel p5 = new JPanel(new GridBagLayout());
        p5.add(new JButton("button 1"), gbc);
        p5.add(new JButton("button 2"), gbc);
        p5.add(new JButton("button 3"), gbc);
        p5.add(new JButton("button 4"), gbc);
        gbc.weighty = 1.0;
        gbc.fill = GridBagConstraints.BOTH;
        p4.add(p5, gbc);

        panels = new JPanel[]{p1, p2, p3, p4};
    }

    private void addComponents(Component c1, Component c2, Container c, GridBagConstraints gbc) {
        gbc.anchor = GridBagConstraints.EAST;
        gbc.gridwidth = GridBagConstraints.RELATIVE;
        c.add(c1, gbc);
        gbc.anchor = GridBagConstraints.WEST;
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        c.add(c2, gbc);
        gbc.anchor = GridBagConstraints.CENTER;
    }

    private JPanel getComponent() {
        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(1, 3, 0, 3);
        gbc.weightx = 1.0;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        for (int j = 0; j < aps.length; j++) {
            panel.add(aps[j], gbc);
            panel.add(panels[j], gbc);
            panels[j].setVisible(false);
        }
        JLabel padding = new JLabel();
        gbc.weighty = 1.0;
        panel.add(padding, gbc);
        return panel;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                ExpandingPanels test = new ExpandingPanels();
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.add(new JScrollPane(test.getComponent()));
                f.setPreferredSize(new Dimension(360, 360));
                f.setLocation(200, 100);
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

class ActionPanel extends JPanel {

    private static final long serialVersionUID = 1L;
    private String text;
    private Font font;
    private boolean selected;
    private BufferedImage open, closed;
    public Rectangle target;
    final int OFFSET = 30,
            PAD = 5;

    ActionPanel(String text, MouseListener ml) {
        this.text = text;
        addMouseListener(ml);
        font = new Font("sans-serif", Font.PLAIN, 12);
        selected = false;
        setBackground(new Color(10, 200, 220));
        setPreferredSize(new Dimension(200, 20));
        setBorder(BorderFactory.createRaisedBevelBorder());
        setPreferredSize(new Dimension(200, 20));
        createImages();
        setRequestFocusEnabled(true);
    }

    public void toggleSelection() {
        selected = !selected;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        int w = getWidth();
        int h = getHeight();
        if (selected) {
            g2.drawImage(open, PAD, 0, this);
        } else {
            g2.drawImage(closed, PAD, 0, this);
        }
        g2.setFont(font);
        FontRenderContext frc = g2.getFontRenderContext();
        LineMetrics lm = font.getLineMetrics(text, frc);
        float height = lm.getAscent() + lm.getDescent();
        float x = OFFSET;
        float y = (h + height) / 2 - lm.getDescent();
        g2.drawString(text, x, y);
    }

    private void createImages() {
        int w = 20;
        int h = getPreferredSize().height;
        target = new Rectangle(2, 0, 20, 18);
        open = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = open.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(getBackground());
        g2.fillRect(0, 0, w, h);
        int[] x = {2, w / 2, 18};
        int[] y = {4, 15, 4};
        Polygon p = new Polygon(x, y, 3);
        g2.setPaint(Color.green.brighter());
        g2.fill(p);
        g2.setPaint(Color.blue.brighter());
        g2.draw(p);
        g2.dispose();
        closed = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        g2 = closed.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(getBackground());
        g2.fillRect(0, 0, w, h);
        x = new int[]{3, 13, 3};
        y = new int[]{4, h / 2, 16};
        p = new Polygon(x, y, 3);
        g2.setPaint(Color.red);
        g2.fill(p);
        g2.setPaint(Color.blue.brighter());
        g2.draw(p);
        g2.dispose();
    }
}

【讨论】:

  • 在 getComponents 中有一个 JLabel padding 有一点(与 jfpoilpret 在他的第二条评论中所说的相同)
【解决方案2】:

如果您不希望您的“内部”面板垂直增长,那么为什么要将 weigthy 设置为 1.0?您应该将其设置为 0.0(至少对于所有不应垂直增长的面板)。

另外,请注意使用边框会影响两个面板之间组件的对齐方式。

在表单中显示不同“部分”的更好方法是对整个表单仅使用一个面板,并使用Jlabel 后跟水平JSeparator 分隔部分。

对于这种形式,我会使用DesignGridLayout(而不是GridBagLayout,因为它太像PITA,无法得到你想要的......),但我在这里有偏见。

【讨论】:

  • 因为weighty为0.0,所以面板居中对齐
  • 在这种情况下,您可以简单地在最后添加一个空面板,weighty = 1.0,它将占用其他面板下方的所有可用空间。
  • 有更好的方法吗?
  • 如果您继续使用 GridBagLayout,我认为没有更好的方法可以做到这一点。您可以考虑使用更好的布局来满足您的需求。
猜你喜欢
  • 1970-01-01
  • 2014-07-20
  • 2015-04-05
  • 2014-06-04
  • 1970-01-01
  • 2014-12-20
  • 2013-01-23
  • 2012-06-24
  • 1970-01-01
相关资源
最近更新 更多