java - 如何使 JLabel float 在 JScrollPane 内的同一 JComponent 之上

标签 java swing jscrollpane jlabel jlayeredpane

有 20 JLabel在里面JScrollPaneJLayeredPane中还添加了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);
            }
        });
    }
}

已解决的问题:

  1. JLabel 11 点击后不完全可见,被裁剪了一半
  2. 我无法计算点击时 float 面板的正确位置
  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);
}

关于java - 如何使 JLabel float 在 JScrollPane 内的同一 JComponent 之上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13626838/

相关文章:

NetBeans 中的 Java Swing Jscrollpane

java - 安卓应用程序 : Can I show products different in a 7 inch tablet from a 10 inch tablet?

java - Saxon:无法使用 XSLT 中的 xs:string 参数调用需要字符串的静态方法

java - spring-shell 和 CRaSH 有什么区别?

java - 使用 Astyanax 创建的键空间对 cqlsh 不可见

java - 让你的 JFrame 成为静态变量是不是很糟糕? ( java Swing )

java - 使用 JOptionPane 显示容纳的数组

java - 如何在Java中播放长声音文件?没有语法错误但没有声音

javascript - 鼠标滚轮无法与 IE8 中的 jScrollPane 一起使用(没有 iframe!)

java - 水平滚动条不适用于 Java Swing 中的 JTable