#java #swing #jpanel
#java #качать #jpanel
Вопрос:
Хорошо, итак, я создал эту JPanel, заполненную шестиугольниками 20 x 20 в форме ромба. Они довольно большие, поэтому вы не можете видеть их все одновременно, но поскольку предполагается, что это карта в игре, я хотел бы использовать прокрутку grab’n’drag.
Фактическое перемещение работает — но когда я перемещаю панель, я удаляю только те плитки, которые я уже мог видеть, плитки, которые должны быть сразу за границами окна, не отображаются. Это похоже на то, что я перемещаю изображение. Однако, если я изменю размер окна, я смогу увидеть больше шестиугольников.
Я пытался принудительно перерисовывать после завершения mouseDragged, но безуспешно. Любой, у кого есть какие-либо идеи, очень рад поделиться ими!
Здесь я показываю все в интерфейсном классе:
ComponentMover comp = new ComponentMover();
comp.registerComponent(gameTiles,this);
main.add(gameTiles, "Game");
cardLayout.show(main, "Game");
и это ComponentMover-класс (заимствованный из http://tips4java.wordpress.com/2009/06/14/moving-windows с несколькими модами)
открытый класс ComponentMover расширяет MouseAdapter {
private Class destinationClass;
private Component destinationComponent;
private Component destination;
private Component source;
private ArrayList<Component>comps;
private boolean changeCursor = true;
private Point pressed;
private Point location;
private Cursor originalCursor;
private boolean autoscrolls;
private Insets dragInsets = new Insets(0, 0, 0, 0);
private Dimension snapSize = new Dimension(1, 1);
/**
* Constructor for moving individual components. The components must be
* regisetered using the registerComponent() method.
*/
public ComponentMover()
{ comps = new ArrayList<Component>();
}
/**
* Constructor to specify a Class of Component that will be moved when
* drag events are generated on a registered child component. The events
* will be passed to the first ancestor of this specified class.
*
* @param destinationClass the Class of the ancestor component
* @param component the Components to be registered for forwarding
* drag events to the ancestor Component.
*/
public ComponentMover(Class destinationClass, Component... components)
{
this.destinationClass = destinationClass;
registerComponent( components );
}
/**
* Constructor to specify a parent component that will be moved when drag
* events are generated on a registered child component.
*
* @param destinationComponent the component drage events should be forwareded to
* @param components the Components to be registered for forwarding drag
* events to the parent component to be moved
*/
public ComponentMover(Component destinationComponent, Component... components)
{
this.destinationComponent = destinationComponent;
registerComponent( components );
}
/**
* Get the change cursor property
*
* @return the change cursor property
*/
public boolean isChangeCursor()
{
return changeCursor;
}
/**
* Set the change cursor property
*
* @param changeCursor when true the cursor will be changed to the
* Cursor.MOVE_CURSOR while the mouse is pressed
*/
public void setChangeCursor(boolean changeCursor)
{
this.changeCursor = changeCursor;
}
/**
* Get the drag insets
*
* @return the drag insets
*/
public Insets getDragInsets()
{
return dragInsets;
}
/**
* Set the drag insets. The insets specify an area where mouseDragged
* events should be ignored and therefore the component will not be moved.
* This will prevent these events from being confused with a
* MouseMotionListener that supports component resizing.
*
* @param dragInsets
*/
public void setDragInsets(Insets dragInsets)
{
this.dragInsets = dragInsets;
}
/**
* Remove listeners from the specified component
*
* @param component the component the listeners are removed from
*/
public void deregisterComponent(Component... components)
{
for (Component component : components)
component.removeMouseListener( this );
}
/**
* Add the required listeners to the specified component
*
* @param component the component the listeners are added to
*/
public void registerComponent(Component... components)
{
for (Component component : components) {
component.addMouseListener( this );
comps.add(component);
}
}
/**
* Get the snap size
*
* @return the snap size
*/
public Dimension getSnapSize()
{
return snapSize;
}
/**
* Set the snap size. Forces the component to be snapped to
* the closest grid position. Snapping will occur when the mouse is
* dragged half way.
*/
public void setSnapSize(Dimension snapSize)
{
this.snapSize = snapSize;
}
/**
* Setup the variables used to control the moving of the component:
*
* source - the source component of the mouse event
* destination - the component that will ultimately be moved
* pressed - the Point where the mouse was pressed in the destination
* component coordinates.
*/
@Override
public void mousePressed(MouseEvent e)
{
source = e.getComponent();
int width = source.getSize().width - dragInsets.left - dragInsets.right;
int height = source.getSize().height - dragInsets.top - dragInsets.bottom;
Rectangle r = new Rectangle(dragInsets.left, dragInsets.top, width, height);
if (r.contains(e.getPoint()))
setupForDragging(e);
}
private void setupForDragging(MouseEvent e)
{
source.addMouseMotionListener( this );
// Determine the component that will ultimately be moved
if (destinationComponent != null)
{
destination = destinationComponent;
}
else if (destinationClass == null)
{
destination = source;
}
else // forward events to destination component
{
destination = SwingUtilities.getAncestorOfClass(destinationClass, source);
}
pressed = e.getLocationOnScreen();
location = destination.getLocation();
if (changeCursor)
{
originalCursor = source.getCursor();
source.setCursor( Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR) );
}
// Making sure autoscrolls is false will allow for smoother dragging of
// individual components
if (destination instanceof JComponent)
{
JComponent jc = (JComponent)destination;
autoscrolls = jc.getAutoscrolls();
jc.setAutoscrolls( false );
}
}
/**
* Move the component to its new location. The dragged Point must be in
* the destination coordinates.
*/
@Override
public void mouseDragged(MouseEvent e)
{
destination.repaint();
Point dragged = e.getLocationOnScreen();
int dragX = getDragDistance(dragged.x, pressed.x, snapSize.width);
int dragY = getDragDistance(dragged.y, pressed.y, snapSize.height);
destination.setLocation(location.x dragX, location.y dragY);
for(Component c : comps)
c.repaint();
}
/*
* Determine how far the mouse has moved from where dragging started
* (Assume drag direction is down and right for positive drag distance)
*/
private int getDragDistance(int larger, int smaller, int snapSize)
{
int halfway = snapSize / 2;
int drag = larger - smaller;
drag = (drag < 0) ? -halfway : halfway;
drag = (drag / snapSize) * snapSize;
return drag;
}
/**
* Restore the original state of the Component
*/
@Override
public void mouseReleased(MouseEvent e)
{
for(Component c : comps)
c.repaint();
System.out.println("Repainted!");
source.removeMouseMotionListener( this );
if (changeCursor)
source.setCursor( originalCursor );
if (destination instanceof JComponent)
{
((JComponent)destination).setAutoscrolls( autoscrolls );
}
}
}
Ответ №1:
ComponentMover используется для изменения расположения компонентов на панели.
Мне кажется, что вы хотите прокрутить панель, содержащуюся в окне просмотра области прокрутки. Если это так, я предлагаю вам проверить метод JComponent.setAutoScrolls(), который содержит некоторый пример кода для прокрутки компонента в области прокрутки.