问题描述
-
如何将GlassPane中的JLabel粘贴到JProgressBar中的相对浮动坐标,而不使用ComponentListener或其他侦听器,
how to stick JLabel in GlassPane to rellative, floating coordinates from JProgressBar without using ComponentListener or another listener,
是否有标准布局管理器中的built_in通知程序可以通知其内部状态,并且可以访问覆盖,而不是我尝试使用ComponentListener和NullLayout
is there built_in notifiers in Standard LayoutManagers that can notify about its internal state, and can be accesible for override, instead my attempt with ComponentListener and NullLayout
。
SSCCE关于 ComponentListener
和 NullLayout
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();
}
}
推荐答案
OverlayLayout 包装在容器中,并用AlignementX / AlignementY播放相对坐标。然后将包装容器放在原始层次结构中。 (请参阅下面的我的SSCCE)
My idea would be to wrap the two components in a container with the OverlayLayout
and "play" with AlignementX/AlignementY for the relative coordinates. Then just put the wrapping container in the original hierarchy. (See my SSCCE below)
LayoutManager API,因此您无法安全地依赖任何此类机制。此外,您将面临标准LayoutManager的问题,因为它们会在布局中考虑额外的 JLabel
。
There is no such contract in the LayoutManager
API, hence you can't rely safely on any such mechanism. Moreover, you will face issues with standard LayoutManager because they will take your extra JLabel
into account in the layout.
想象一下,你使用 FlowLayout
然后你输入1个组件,然后是额外的 JLabel
,然后是另一个组件。当您移动额外的 JLabel
时,最后一个组件将与第一个组件保持距离,您将看到这两个组件之间存在差距。
Imagine you use FlowLayout
and you put 1 component, then your extra JLabel
, then another component. When you move the extra JLabel
the last component will remain "away" from the first component and you will see a gap between these two.
如果最后一个问题不是问题,你可以简单地扩展 FlowLayout
(或任何其他 LayoutManager
),覆盖 layoutContainer
并在您想要的任何地方放置额外的 JLabel
。
If this last issue is not a problem, you could simply extend FlowLayout
(or any other LayoutManager
), override layoutContainer
and place the extra JLabel
wherever you would like.
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();
}
}
这篇关于布局管理器和定位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!