Я написал MouseListener
, как определено ниже, чтобы я мог перемещать JButton
, чтобы изменить порядок компонентов, которые находятся внутри JPanel
. JPanel
находится внутри JScrollPane
, поэтому при добавлении нескольких компонентов их можно прокручивать.
Проблема, с которой я сталкиваюсь, заключается в том, что при перетаскивании компонента и выходе мыши из области прокрутки/окна просмотра компонент возвращается к своей позиции в пределах JPanel
, а затем отрисовывается в правильном месте. Я предполагаю, что это поведение связано с тем, что Viewport вызывает перерисовку своих дочерних элементов, когда я вызываю scrollRectToVisible()
Есть ли способ предотвратить это?
Обратите внимание, что я ограничен Java 5
Слушатель
import java.awt.Component;
import java.awt.Container;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.event.MouseInputAdapter;
public class DragListener extends MouseInputAdapter
{
private Point location;
private MouseEvent pressed;
private MouseEvent dragged;
private MouseEvent dropped;
@Override
public void mousePressed(MouseEvent me)
{
pressed = me;
}
@Override
public void mouseDragged(MouseEvent me)
{
dragged = me;
Component component = dragged.getComponent();
Container parent = component.getParent();
Container superParent = parent.getParent();
if(superParent instanceof JViewport)
{
JViewport vp = (JViewport)superParent;
Rectangle vpb = vp.getBounds();
Point pt = MouseInfo.getPointerInfo().getLocation();
SwingUtilities.convertPointFromScreen(pt, vp);
if(!vpb.contains(pt))
{
int yDiff = (pt.y < vpb.y ) ? pt.y : pt.y - vpb.height;
vpb.translate(0, yDiff);
vp.scrollRectToVisible(vpb);
}
}
location = component.getLocation(location);
int x = location.x - pressed.getX() + me.getX();
int y = location.y - pressed.getY() + me.getY();
component.setLocation(x, y);
}
// Mouse release omitted
}
Графический интерфейс (создан в NetBeans)
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class DragginTest extends javax.swing.JFrame
{
public DragginTest()
{
initComponents();
addListeners(jButton1, jButton2, jButton3, jButton4, jButton5, jButton6, jButton7, jButton8, jButton9);
}
private void addListeners(JButton... buttons)
{
DragListener drag = new DragListener();
for(JButton b : buttons)
{
b.addMouseListener(drag);
b.addMouseMotionListener(drag);
}
}
@SuppressWarnings("unchecked")
private void initComponents()
{
jLayeredPane1 = new javax.swing.JLayeredPane();
jScrollPane1 = new javax.swing.JScrollPane();
mainPanel = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
jButton3 = new javax.swing.JButton();
jButton4 = new javax.swing.JButton();
jButton5 = new javax.swing.JButton();
jButton6 = new javax.swing.JButton();
jButton7 = new javax.swing.JButton();
jButton8 = new javax.swing.JButton();
jButton9 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setPreferredSize(new java.awt.Dimension(450, 450));
mainPanel.setLayout(new java.awt.GridLayout(5, 2, 2, 2));
// Below Repeated for buttons 1-9 (left out for conciseness)
jButton1.setFont(new java.awt.Font("Tahoma", 1, 48)); // NOI18N
jButton1.setForeground(new java.awt.Color(255, 0, 0));
jButton1.setText("1");
mainPanel.add(jButton1);
// End Repeat
jScrollPane1.setViewportView(mainPanel);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(40, 40, 40)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 205, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(38, 38, 38))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(40, 40, 40)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 226, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(53, Short.MAX_VALUE))
);
pack();
}
public static void main(String args[])
{
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run()
{
new DragginTest().setVisible(true);
}
});
}
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JButton jButton3;
private javax.swing.JButton jButton4;
private javax.swing.JButton jButton5;
private javax.swing.JButton jButton6;
private javax.swing.JButton jButton7;
private javax.swing.JButton jButton8;
private javax.swing.JButton jButton9;
private javax.swing.JLayeredPane jLayeredPane1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JPanel mainPanel;
}
JScrollPane
. - person MadProgrammer   schedule 25.05.2015