JLayeredPane和GridBagConstraints [英] JLayeredPane and GridBagConstraints

查看:95
本文介绍了JLayeredPane和GridBagConstraints的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

受此问题启发 带有LayoutManager的JLayeredPane 我正在尝试让JLayeredPane与GridBagLayout一起使用.

Inspired by this question JLayeredPane with a LayoutManager I'm trying to get the JLayeredPane to work with the GridBagLayout.

这是自定义的LayeredPane类:

Here's the custom LayeredPane-class:

class StackConstraints {
    public final int layer;
    public final Object layoutConstraints;

    public StackConstraints(int layer, Object layoutConstraints) {
        this.layer = layer;
        this.layoutConstraints = layoutConstraints;
    }
}

class LXLayeredPane extends JLayeredPane {

    private static final long serialVersionUID = 1946283565823567689L;

    @Override
    protected void addImpl(Component comp, Object constraints, int index) {
        int layer = 0;
        int pos = 0;
        Object constr = null;
        if (constraints instanceof StackConstraints) {
            layer = ((StackConstraints) constraints).layer;
            constr = ((StackConstraints) constraints).layoutConstraints;
        } else {
            layer = getLayer(comp);
            constr = constraints;
        }

        pos = insertIndexForLayer(layer, index);
        super.addImpl(comp, constr, pos);
        setLayer(comp, layer, pos);
        comp.validate();
        comp.repaint();
    }
}

这是一个简单的演示(类似于标准JLayeredPane演示,但适用于GridBagConstraints的使用,并去除了不必要的内容).

And here's a simple demo (similar to the standard-JLayeredPane demo but adapted for the usage of GridBagConstraints and stripped of the unnecessary stuff).

public class LayeredPaneDemo extends JPanel implements ActionListener {
    private final Color[] layerColors = { Color.yellow, Color.magenta, Color.cyan, Color.red, Color.green, Color.blue };

    private final JLayeredPane layeredPane;
    private final List<JLabel> labels;

    private JButton update;

    public LayeredPaneDemo() {
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));

        labels = new ArrayList<>();

        layeredPane = new LXLayeredPane();
        layeredPane.setPreferredSize(new Dimension(400, 410));
        layeredPane.setBorder(BorderFactory.createTitledBorder("Click to change colors"));

        // Add several labels to the layered pane.
        layeredPane.setLayout(new GridBagLayout());
        for (int i = 0; i < layerColors.length; i++) {
            JLabel label = createColoredLabel("Test", layerColors[i]);
            labels.add(label);
            layeredPane.add(label, new StackConstraints(i, gbc(i)));
        }

        // Add control pane and layered pane to this JPanel.
        add(Box.createRigidArea(new Dimension(0, 10)));
        add(createControlPanel());
        add(Box.createRigidArea(new Dimension(0, 10)));
        add(layeredPane);
    }

    private GridBagConstraints gbc(int i) {
        return new GridBagConstraints(i, i, 2, 2, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                new Insets(0, 0, 0, 0), 0, 0);
    }

    // Create and set up a colored label.
    private JLabel createColoredLabel(String text, Color color) {
        JLabel label = new JLabel(text);
        label.setVerticalAlignment(JLabel.TOP);
        label.setHorizontalAlignment(JLabel.CENTER);
        label.setOpaque(true);
        label.setBackground(color);
        label.setForeground(Color.black);
        label.setBorder(BorderFactory.createLineBorder(Color.black));
        label.setPreferredSize(new Dimension(240, 240));
        return label;
    }

    // Create the control pane for the top of the frame.
    private JPanel createControlPanel() {
        update = new JButton("Update");
        update.addActionListener(this);
        update.setActionCommand("UPDATE");

        JPanel controls = new JPanel();
        controls.add(update);
        controls.setBorder(BorderFactory.createTitledBorder("Choose Duke's Layer and Position"));
        return controls;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Color prev = labels.get(labels.size() - 1).getBackground();

        for (int i = labels.size() - 1; i > 0; --i) {
            labels.get(i).setBackground(labels.get(i - 1).getBackground());
            labels.get(i).validate();
            labels.get(i).repaint();
        }
        labels.get(0).setBackground(prev);
        labels.get(0).validate();
        labels.get(0).repaint();
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("LayeredPaneDemo2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JComponent newContentPane = new LayeredPaneDemo();
        newContentPane.setOpaque(true);
        frame.setContentPane(newContentPane);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }

}

我的问题是我要添加6个(六个!)标签,但仅显示5个(五个!).第零只消失在某个地方.是什么原因呢?

My problem is that I'm adding 6 (six!) labels but only 5 (five!) are displayed. The 0-th one just vanishes somewhere. What's the reason for that?

编辑:追求这一目标的最初动机是将一个(部分透明的)组件放置在另一个组件的顶部,如此屏幕截图所示 显示17:00:09的标签具有透明背景,并放置在图表组件的顶部.需要GridBagLayout才能将其准确地放置在图表的顶部中间.

The initial motivation behind the pursuit is to place one (partially transparent) component on top of another like in this screenshot The label displaying 17:00:09 has transparent background and is placed on top of the chart-component. GridBagLayout is needed to place it exactly at the top middle of the chart.

推荐答案

  • 正如@camickr所说,JLayeredPane无关紧要.
  • 看看 GridBagLayout创建板| Oracle社区.可能有帮助.

    • As @camickr has already said, JLayeredPane is irrelevant.
    • Take a look at GridBagLayout to create a board | Oracle Community. May be it helps.

      达里尔·伯克(Darryl.Burke)说:
      除非至少有一个组件仅占据该列(或行),否则GridBagLayout中的列(或行)定义不明确.您所有的行都有跨越2列的组件.

      Darryl.Burke said:
      A column (or row) in a GridBagLayout is not well defined unless there is at least one component which occupies only that column (or row). All your rows have components spanning 2 columns.

    • import java.awt.*;
      import java.awt.event.*;
      import java.util.ArrayList;
      import java.util.List;
      import javax.swing.*;
      import javax.swing.table.*;
      
      public class LayeredPaneDemo2 extends JPanel implements ActionListener {
        private final Color[] layerColors = {
            Color.yellow, Color.magenta, Color.cyan,
            Color.red, Color.green, Color.blue };
      
        private final JLayeredPane layeredPane;
        private final List<JLabel> labels;
      
        private JButton update;
      
        public LayeredPaneDemo2() {
          setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
      
          labels = new ArrayList<>();
          // JLayeredPane is not much related, it is a problem of how to use GridBagLayout.
          layeredPane = new LXLayeredPane();
          layeredPane.setPreferredSize(new Dimension(400, 410));
          layeredPane.setBorder(BorderFactory.createTitledBorder(
              "Click to change colors"));
      
          // Add several labels to the layered pane.
          layeredPane.setLayout(new GridBagLayout());
      
          for (int i = 0; i < layerColors.length; i++) {
            JLabel label = createColoredLabel("Test" + i, layerColors[i]);
            labels.add(label);
            layeredPane.add(label, new StackConstraints(i, gbc(i)));
          }
      //     //TEST1: Create reference grid
      //     GridBagConstraints c = new GridBagConstraints(
      //       0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
      //       GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0);
      //     for (int i = 0; i < layerColors.length + 1; i++) {
      //       c.gridx = i;
      //       c.gridy = i;
      //       layeredPane.add(Box.createRigidArea(new Dimension(20, 20)), c);
      //     }
          //TEST2: Create reference grid >>>
          GridBagConstraints c = new GridBagConstraints(
              6, 6, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
              GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0);
          for (int i = 0; i < layerColors.length; i++) {
            c.gridx = i;
            Component box = Box.createRigidArea(new Dimension(20, 20));
            ((JComponent) box).setBorder(BorderFactory.createLineBorder(Color.RED));
            layeredPane.add(box, c);
          }
          c.gridx = 6;
          for (int i = 0; i < layerColors.length; i++) {
            c.gridy = i;
            Component box = Box.createRigidArea(new Dimension(20, 20));
            ((JComponent) box).setBorder(BorderFactory.createLineBorder(Color.RED));
            layeredPane.add(box, c);
          }
          // <<<
          // Add control pane and layered pane to this JPanel.
          add(Box.createRigidArea(new Dimension(0, 10)));
          add(createControlPanel());
          add(Box.createRigidArea(new Dimension(0, 10)));
          add(layeredPane);
        }
      
        private GridBagConstraints gbc(int i) {
          return new GridBagConstraints(
              i, i, 2, 2, 0.0, 0.0, GridBagConstraints.CENTER,
              GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0);
        }
      
        // Create and set up a colored label.
        private JLabel createColoredLabel(String text, Color color) {
          JLabel label = new JLabel(text) {
            @Override protected void paintComponent(Graphics g) {
              g.setColor(new Color(100, 100, 100, 100));
              g.fillRect(0, 0, getWidth(), getHeight());
              super.paintComponent(g);
            }
          };
          label.setVerticalAlignment(JLabel.TOP);
          label.setHorizontalAlignment(JLabel.CENTER);
          label.setOpaque(true);
          label.setBackground(color);
          label.setForeground(Color.black);
          label.setBorder(BorderFactory.createLineBorder(Color.black));
          label.setPreferredSize(new Dimension(240, 240));
          return label;
        }
      
        // Create the control pane for the top of the frame.
        private JPanel createControlPanel() {
          update = new JButton("Update");
          update.addActionListener(this);
          update.setActionCommand("UPDATE");
      
          JPanel controls = new JPanel();
          controls.add(update);
          controls.setBorder(BorderFactory.createTitledBorder(
              "Choose Duke's Layer and Position"));
          return controls;
        }
      
        @Override
        public void actionPerformed(ActionEvent e) {
          Color prev = labels.get(labels.size() - 1).getBackground();
      
          for (int i = labels.size() - 1; i > 0; --i) {
            labels.get(i).setBackground(labels.get(i - 1).getBackground());
            labels.get(i).validate();
            labels.get(i).repaint();
          }
          labels.get(0).setBackground(prev);
          labels.get(0).validate();
          labels.get(0).repaint();
        }
      
        private static void createAndShowGUI() {
          JFrame frame = new JFrame("LayeredPaneDemo2");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      
          JComponent newContentPane = new LayeredPaneDemo2();
          newContentPane.setOpaque(true);
          frame.setContentPane(newContentPane);
      
          frame.pack();
          frame.setVisible(true);
        }
      
        public static void main(String[] args) {
          javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
              createAndShowGUI();
            }
          });
        }
      
      }
      
      class StackConstraints {
        public final int layer;
        public final Object layoutConstraints;
      
        public StackConstraints(int layer, Object layoutConstraints) {
          this.layer = layer;
          this.layoutConstraints = layoutConstraints;
        }
      }
      
      class LXLayeredPane extends JLayeredPane {
        @Override
        protected void addImpl(Component comp, Object constraints, int index) {
          int layer = 0;
          int pos = 0;
          Object constr = null;
          if (constraints instanceof StackConstraints) {
            layer = ((StackConstraints) constraints).layer;
            constr = ((StackConstraints) constraints).layoutConstraints;
          } else {
            layer = getLayer(comp);
            constr = constraints;
          }
      
          pos = insertIndexForLayer(layer, index);
          super.addImpl(comp, constr, pos);
          setLayer(comp, layer, pos);
          comp.validate();
          comp.repaint();
        }
      }
      

      这篇关于JLayeredPane和GridBagConstraints的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆