2

里面有20JLabelJScrollPaneJLayeredPane上面提到的还有floatingLabel JscrollPane

要求是,当我单击内部时JScrollPane,它应该自动滚动以使JLabel索引 11完全可见。JLabel当用户滚动时, floatingLabel 应该开始在 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. 单击时我无法计算浮动面板的正确位置
  3. 我不知道如何计算滚动时的新位置
4

1 回答 1

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);
}
于 2012-11-29T13:49:34.853 回答