如何使JLabel浮动在JScrollPane内的相同JComponent之上

时间:2012-11-29 13:24:58

标签: java swing jscrollpane jlabel jlayeredpane

JLabel内有JScrollPaneJLayeredPane。还有一个floatingLabel与上面提到的JscrollPane一起添加到JScrollPane

要求是当我在JLabel内点击时,它应自动滚动以使JLabel索引11 完全可见。当用户滚动JScrollPane时,floatingLabel也应该在AdjustmentListener 11之上浮动,请参阅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); } }); } }

问题[编辑]: 1.如何检查JLabel 11是否完全或部分不可见?

SSCCE:

{{1}}

解决了问题:

  1. 点击后JLabel 11不完全可见,它是半裁剪
  2. 我无法在点击
  3. 上计算floatingPanel的正确位置
  4. 我不知道如何计算滚动的新位置

1 个答案:

答案 0 :(得分:3)

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);
}