Answer the question
In order to leave comments, you need to log in
Why is the window (java.awt.Window) redrawn incorrectly?
I'm not satisfied with the standard toolbar docking mechanism in Swing, so I'm making my own implementation.
When dragging a toolbar from one edge of the component to the other, a window (java.awt.Window) appears, which takes the size of the dragged toolbar, taking into account its orientation.
The position of the window is determined by the current coordinates of the cursor. Depending on whether the toolbar can be moved to its current position, the color of the lines and the background color in the window change.
Here are screenshots of what it looks like.
Window near the horizontal edge:
Window indicating that the toolbar cannot be placed here
. Window near the vertical edge:
The problem is the following. When a toolbar is dragged and the cursor moves from one edge of the component to another (for example, from the left to the top), this window shows both the newly drawn state and part of the previous one. It looks as if a new state is being drawn, and an old state is being drawn on top of it, but due to the fact that the window size has changed to the opposite, the rendered old state does not fit completely, and only a part of it is visible.
Here is a screenshot of such a state:
Here is the code:
package ru.kih.gui.toolbar;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import ru.kih.gui.graph.Colors;
public class DragWindowHandler implements DragEffectHandler {
private final ToolbarSupport toolbarSupport;
private final DragWindow dragWindow;
public DragWindowHandler(ToolbarSupport toolbarSupport) {
this.toolbarSupport = toolbarSupport;
this.dragWindow = new DragWindow(SwingUtilities.getWindowAncestor(toolbarSupport.getRoot()));
}
@Override
public void showDragEffect(Dimension size, Point p, final boolean canDock) {
final Point location = getLocation(p, size);
final Rectangle rect = new Rectangle(location, size);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
dragWindow.setCanDock(canDock);
dragWindow.setBounds(rect);
if ( !dragWindow.isVisible() ) {
dragWindow.setVisible(true);
}
}
});
}
private Point getLocation(Point p, Dimension size) {
Point location = new Point(p);
SwingUtilities.convertPointToScreen(location, toolbarSupport.getRoot());
int offsetX = size.width / 2;
int offsetY = size.height / 2;
location.x -= offsetX;
location.y -= offsetY;
return location;
}
@Override
public void hideDragEffect() {
dragWindow.setVisible(false);
}
private class DragWindow extends Window {
private boolean canDock;
private Color frameColor;
private int lineTickness = 3;
public DragWindow(Window owner) {
super(owner);
}
public boolean isCanDock() {
return canDock;
}
public void setCanDock(boolean canDock) {
if ( this.canDock == canDock ) {
return;
}
this.canDock = canDock;
repaint();
}
@Override
public void paint(Graphics g) {
//super.paint(g);
Graphics2D g2 = (Graphics2D) g;
Dimension size = getSize();
final Color color = getFrameColor();
Color fillColor = canDock ? new Colors(color).a(.5f).build() : getBackground();
Color lineColor = canDock ? color : new Colors(color).a(.2f).build();
g2.setColor(getBackground());
g2.fillRect(0, 0, size.width, size.height);
g2.setColor(fillColor);
g2.fillRect(0, 0, size.width, size.height);
g2.setColor(lineColor);
g2.setStroke(new BasicStroke(lineTickness));
g2.drawRect(lineTickness / 2, lineTickness / 2, size.width - lineTickness, size.height - lineTickness);
}
private Color getFrameColor() {
if(frameColor == null) {
frameColor = UIManager.getColor("Tree.dropLineColor");
if(frameColor == null) {
frameColor = Color.RED;
}
}
return frameColor;
}
}
}
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question