【问题标题】:Layout Manager and Positioning布局管理器和定位
【发布时间】:2013-08-21 11:18:28
【问题描述】:
  • 如何在不使用 ComponentListener 或其他侦听器的情况下将 GlassPane 中的 JLabel 粘贴到来自 JProgressBar 的相对浮动坐标,

  • 标准 LayoutManagers 中是否有内置通知器可以通知其内部状态,并且可以覆盖,而不是我尝试使用 ComponentListener 和 NullLayout

.

SSCCE 关于ComponentListenerNullLayout

import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.UIManager;
//http://stackoverflow.com/questions/14560680/jprogressbar-low-values-will-not-be-displayed
public class ProgressSample {

    private JFrame frame = new JFrame("GlassPane instead of JLayer");
    private JLabel label;
    private GridBagConstraints gbc = new GridBagConstraints();
    private JProgressBar progressSeven;

    public ProgressSample() {
        frame.setLayout(new FlowLayout());
        frame.add(new JButton("test"));
        frame.add(new JCheckBox("test"));
        frame.add(new JRadioButton("test"));
        // Nothing is displayed if value is lover that 6
        JProgressBar progressSix = new JProgressBar(0, 100);
        progressSix.setValue(2);
        frame.add(progressSix);
        // but this works value is higher that 6
        progressSeven = new JProgressBar(0, 100);
        progressSeven.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentMoved(ComponentEvent e) {
                label.setBounds(
                        (int) progressSeven.getBounds().getX(),
                        (int) progressSeven.getBounds().getY(),
                        progressSeven.getPreferredSize().width,
                        label.getPreferredSize().height);
            }
        });
        progressSeven.setValue(7);
        frame.add(progressSeven);
        label = new JLabel();
        label.setText("<html>Blablabla, Blablablabla<br>"
                + "Blablabla, Blablablabla<br>"
                + "Blablabla, Blablablabla</html>");
        label.setPreferredSize(new Dimension(
                progressSeven.getPreferredSize().width,
                label.getPreferredSize().height));
        Container glassPane = (Container) frame.getRootPane().getGlassPane();
        glassPane.setVisible(true);
        glassPane.setLayout(null);
        glassPane.add(label, gbc);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        ProgressSample dialogTest = new ProgressSample();
    }
}

【问题讨论】:

  • layoutContainer() 可以被覆盖以触发可以由玻璃窗格的自定义布局管理器侦听的事件。我不确定这是否是你想要的。
  • 不使用 ComponentListener 或其他监听器 多么奇怪的要求,作业?
  • @kleopatra 我不能隐藏那个吗??? :-)

标签: java swing layout-manager glasspane componentlistener


【解决方案1】:

如何将 GlassPane 中的 JLabel 粘贴到相对的浮动坐标上 从 JProgressBar 不使用 ComponentListener 或其他监听器

我的想法是使用OverlayLayout 将这两个组件包装在一个容器中,并使用 AlignementX/AlignementY 来“播放”相对坐标。然后只需将包装容器放在原始层次结构中。 (见下面我的 SSCCE)

标准布局管理器中是否有内置的通知器可以通知 关于它的内部状态,并且可以被覆盖,而不是 我对 ComponentListener 和 NullLayout 的尝试

LayoutManager API 中没有这样的合约,因此你不能安全地依赖任何这样的机制。此外,您将面临标准 LayoutManager 的问题,因为它们会在布局中考虑您额外的 JLabel

想象一下,您使用FlowLayout,然后放入一个组件,然后是额外的JLabel,然后是另一个组件。当您移动额外的 JLabel 时,最后一个组件将保持“远离”第一个组件,您会看到这两者之间存在间隙。

如果最后一个问题不是问题,您可以简单地扩展 FlowLayout(或任何其他 LayoutManager),覆盖 layoutContainer 并将额外的 JLabel 放置在您想要的任何位置。

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.OverlayLayout;
import javax.swing.UIManager;

//http://stackoverflow.com/questions/14560680/jprogressbar-low-values-will-not-be-displayed
public class ProgressSample {

    private JFrame frame = new JFrame("GlassPane instead of JLayer");
    private JLabel label;
    private GridBagConstraints gbc = new GridBagConstraints();
    private JProgressBar progressSeven;

    public ProgressSample() {
        frame.setLayout(new FlowLayout());
        frame.add(new JButton("test"));
        frame.add(new JCheckBox("test"));
        frame.add(new JRadioButton("test"));
        // Nothing is displayed if value is lover that 6
        JProgressBar progressSix = new JProgressBar(0, 100);
        progressSix.setValue(2);
        frame.add(progressSix);
        JPanel wrappingPanel = new JPanel();
        OverlayLayout mgr = new OverlayLayout(wrappingPanel);
        wrappingPanel.setLayout(mgr);
        progressSeven = new JProgressBar(0, 100);
        progressSeven.setAlignmentX(0.0f);
        progressSeven.setAlignmentY(0.0f);
        frame.add(wrappingPanel);
        label = new JLabel();
        label.setText("<html>Blablabla, Blablablabla<br>" + "Blablabla, Blablablabla<br>" + "Blablabla, Blablablabla</html>");
        label.setAlignmentX(0.0f);
        label.setAlignmentY(0.0f);
        wrappingPanel.add(label);
        wrappingPanel.add(progressSeven);
        Container glassPane = (Container) frame.getRootPane().getGlassPane();
        glassPane.setVisible(true);
        glassPane.setLayout(new FlowLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        ProgressSample dialogTest = new ProgressSample();
    }
}

【讨论】:

  • +1 hmmm 同意,可能会回答我的问题.....,然后更好,更安全可以使用JProgressBar as Container(as always for me),顺便说一句,这个问题是基于我对那里发布的代码的知识缺乏作为我的答案,
  • @mKorbel 使用JProgressBar 作为容器有一个缺点:进度条会延伸到提供的整个边界,所以看起来很奇怪。
  • 边界是副作用,由使用的 LayoutManager 引起,例如GBC 对 JPanel 造成了同样的问题,你说得对,这在 Swing 中不是标准的,在 Htlm5/JavaFX 中的要求很高
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
  • 1970-01-01
  • 2018-06-12
  • 2016-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多