2

JLabel内部には20秒ありJScrollPaneます。上記とJLayeredPane一緒に追加される floatingLabel もあります。JscrollPane

要件は、内部をクリックすると、インデックス 11が完全に表示されるようにJScrollPane自動的にスクロールする必要があることです。また、floatingLabel は、ユーザーがスクロールしたときにその 11 より上でフローティングを開始する必要があります。を参照してください。JLabelJLabelJScrollPaneAdjustmentListener

問題 [編集]: 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 に答える