有 20 JLabel
在里面JScrollPane
。 JLayeredPane
中还添加了floatingLabel与 JscrollPane
一起上文提到的。
要求是当我点击里面JScrollPane
时它应该自动滚动以生成 JLabel
索引 11 完全可见。此外,floatingLabel 应该开始 float 在 JLabel
上方。 11 当用户滚动时JScrollPane
,引用AdjustmentListener
.
问题[编辑]: 1. 如何检查 JLabel 11 是否完全或部分不可见?
SSCCE:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class JScrollPaneTest {
protected ArrayList<JLabel> labels = new ArrayList<JLabel>();
protected JLabel floatingLabel = new JLabel("floating");
protected JFrame frame;
protected JScrollPane sPane;
protected JLayeredPane lPane;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new JScrollPaneTest();
}
});
}
public JScrollPaneTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
lPane = new JLayeredPane() {
private static final long serialVersionUID = 1L;
@Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
};
JPanel panel = new JPanel ();
panel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
for (int i = 0; i < 20; i++) {
JLabel label = new JLabel(" | Label" + i + " | ");
panel.add(label, gbc);
labels.add(label);
}
panel.addMouseListener(new MouseAdapter(){
public void mousePressed (MouseEvent me) {
JLabel label = labels.get(11);
label.scrollRectToVisible(label.getBounds());
Point loc = label.getLocation();
Point wrPos = SwingUtilities.convertPoint(label, loc, lPane);
floatingLabel.setLocation(wrPos);
floatingLabel.setVisible(true);
}
});
sPane = new JScrollPane(panel) {
private static final long serialVersionUID = 1L;
@Override
public Dimension getPreferredSize() {
return new Dimension(600, 400);
}
};
sPane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent ae) {
System.out.println("adjustmentValueChanged: " + ae.getValue());
//if label11 is not visible
//floatingLabel.setVisible(false);
//else floatingLabel.setLocation();
}
});
lPane.add(sPane, JLayeredPane.PALETTE_LAYER);
sPane.setBounds(100, 100, (int)sPane.getPreferredSize().getWidth(), (int)sPane.getPreferredSize().getHeight());
lPane.add(floatingLabel, JLayeredPane.POPUP_LAYER);
floatingLabel.setBounds(100, 100, 50, 30);
floatingLabel.setBorder(BorderFactory.createLineBorder(Color.red));
frame.getContentPane().add(lPane);
frame.pack();
frame.setVisible(true);
}
});
}
}
已解决的问题:
- JLabel 11 点击后不完全可见,被裁剪了一半
- 我无法计算点击时 float 面板的正确位置
- 我不知道如何计算滚动时的新位置
最佳答案
label.scrollRectToVisible(new Rectangle(0,0,label.getWidth(), label.getHeight()));
在点击中使用它
public void mousePressed (MouseEvent me) {
JLabel label = labels.get(11);
label.scrollRectToVisible(new Rectangle(0,0,label.getWidth(), label.getHeight()));
//Point loc = label.getLocation();
Point loc = new Point(0,0);
Point wrPos = SwingUtilities.convertPoint(label, loc, lPane);
floatingLabel.setLocation(wrPos);
floatingLabel.setVisible(true);
}
public void adjustmentValueChanged(AdjustmentEvent ae) {
System.out.println("adjustmentValueChanged: " + ae.getValue());
JLabel label = labels.get(11);
Point loc = new Point(0,0);
Point wrPos = SwingUtilities.convertPoint(label, loc, lPane);
floatingLabel.setLocation(wrPos);
floatingLabel.setVisible(true);
}
关于java - 如何使 JLabel float 在 JScrollPane 内的同一 JComponent 之上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13626838/