在JScrollPane中手动移动JComponent

时间:2015-06-27 10:44:23

标签: java swing jscrollpane

我试图创建一个程序,让用户手动在JScrollPane中放置和调整组件,这是一个特殊的UI Builder。我设法创建了一个自定义JPanel类,允许用户手动移动它,但是当它被添加到JScrollPane并移动时,如果它超出了JScrollPane的视觉界限,则滚动条不会出现或调整。

这是我的主要类,包括JFrame和JScrollPane。

package quickscrolltest;

import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class QuickScrollTest {

    JFrame wnd;
    JScrollPane scroll;
    JPanel pnl;
    MovablePanel pnl1;

    public QuickScrollTest() {
        wnd = new JFrame();
        scroll = new JScrollPane();
        pnl = new JPanel();
        pnl.setLayout(null);
        scroll.setViewportView( pnl );
        wnd.setContentPane(scroll);
        wnd.pack();
        pnl1 = new MovablePanel();
        Dimension dim1 = new Dimension( 300, 400 );
        pnl1.setSize( dim1 );        
        pnl1.setPreferredSize(dim1);
        pnl1.setBackground( Color.CYAN );
        pnl1.setLocation( 10, 10 );
        /*scroll.getViewport().add(pnl1,null);*/
        pnl.add(pnl1);
        wnd.setSize( 800, 600 );
        wnd.setLocationRelativeTo(null);
        wnd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        wnd.setVisible(true);
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new QuickScrollTest();
    }

}

这是MovablePanel类

package quickscrolltest;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JPanel;

public class MovablePanel extends JPanel implements MouseListener, MouseMotionListener {

    Color bg = Color.GRAY;
    Point clickPoint;

    public MovablePanel() {
        addMouseListener(this);
        addMouseMotionListener(this);
    }

    @Override
    public void setBackground( Color col ) {
        super.setBackground(col);
        bg = col;
    }

    @Override
    public void mouseClicked(MouseEvent e) {}

    @Override
    public void mousePressed(MouseEvent e) {
        clickPoint = e.getPoint();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        setCursor( Cursor.getDefaultCursor() );
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        setCursor( Cursor.getPredefinedCursor(Cursor.HAND_CURSOR) );
        super.setBackground( Color.RED );
    }

    @Override
    public void mouseExited(MouseEvent e) {
        setCursor( Cursor.getDefaultCursor() );
        super.setBackground( bg );
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        setCursor( Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR) );
        int lastX = getX() - (int) clickPoint.getX();
        int lastY = getY() - (int) clickPoint.getY();
        setLocation(lastX + e.getX(), lastY + e.getY() );
    }

    @Override
    public void mouseMoved(MouseEvent e) {}  

}

如何创建它以便用户可以在JScrollPane中自由移动组件并根据需要更新滚动条?

我的最终代码将有一个独立的mouselistener / mousemotionlistener类,它通常适用于给定的JComponent,但为了简单起见,我将侦听器直接编码到JPanel中。

由于

1 个答案:

答案 0 :(得分:0)

当滚动窗格视口中显示的组件的首选大小发生变化时,滚动条会自动显示/消失。

您可以使用Drag Layout。此类是一个自定义布局管理器,当组件在面板上拖动时,它将自动重新计算面板的首选大小。

您需要处理mouseReleased事件,以便revalidate()面板,并在完成拖动组件后调用DragLayout,以便重置首选大小。或者您可以使用博客文章中引用的ComponentMover类来为您拖动组件。它支持auto resize属性,它将为您执行revalidate()。