Browse Source

Improved rendering for popupmenus that are too large for the screen.

pull/130/head
weisj 5 years ago
parent
commit
a3587d02db
  1. 125
      core/src/main/java/com/github/weisj/darklaf/components/ScrollPopupMenu.java
  2. 4
      core/src/main/java/com/github/weisj/darklaf/ui/combobox/DarkComboPopup.java
  3. 1
      core/src/main/java/com/github/weisj/darklaf/ui/popupmenu/DarkPopupMenuBorder.java
  4. 37
      core/src/main/java/com/github/weisj/darklaf/ui/popupmenu/DarkPopupMenuUI.java
  5. 139
      core/src/main/java/com/github/weisj/darklaf/ui/popupmenu/PopupMenuContainer.java
  6. 4
      core/src/main/java/com/github/weisj/darklaf/ui/scrollpane/DarkScrollBarUI.java
  7. 32
      core/src/main/java/com/github/weisj/darklaf/ui/tooltip/ToolTipUtil.java
  8. 41
      core/src/main/java/com/github/weisj/darklaf/util/DarkUIUtil.java

125
core/src/main/java/com/github/weisj/darklaf/components/ScrollPopupMenu.java

@ -23,12 +23,10 @@
*/ */
package com.github.weisj.darklaf.components; package com.github.weisj.darklaf.components;
import com.github.weisj.darklaf.util.DarkUIUtil; import com.github.weisj.darklaf.ui.popupmenu.PopupMenuContainer;
import com.github.weisj.darklaf.util.PropertyKey; import com.github.weisj.darklaf.util.PropertyKey;
import javax.swing.*; import javax.swing.*;
import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;
import java.awt.*; import java.awt.*;
/** /**
@ -36,60 +34,16 @@ import java.awt.*;
*/ */
public class ScrollPopupMenu extends JPopupMenu { public class ScrollPopupMenu extends JPopupMenu {
private final JPanel contentPane; private final PopupMenuContainer popupMenuContainer;
private final JScrollPane scrollPane;
private int maxHeight; private int maxHeight;
private JWindow popWin; private Popup popup;
private int posX; private int posX;
private int posY; private int posY;
private JPanel view; private boolean isVisible;
public ScrollPopupMenu(final int maxHeight) { public ScrollPopupMenu(final int maxHeight) {
popupMenuContainer = new PopupMenuContainer();
this.maxHeight = maxHeight; this.maxHeight = maxHeight;
contentPane = new JPanel(new BorderLayout());
OverlayScrollPane overlayScrollPane = createScrollPane();
scrollPane = overlayScrollPane.getScrollPane();
contentPane.add(overlayScrollPane, BorderLayout.CENTER);
contentPane.setBorder(getBorder());
setDoubleBuffered(true);
MenuKeyListener menuKeyListener = new MenuKeyListener() {
@Override
public void menuKeyTyped(final MenuKeyEvent e) {
}
@Override
public void menuKeyPressed(final MenuKeyEvent e) {
SwingUtilities.invokeLater(() -> {
MenuElement[] path = e.getMenuSelectionManager().getSelectedPath();
if (path.length == 0) {
return;
}
Rectangle bounds = path[path.length - 1].getComponent().getBounds();
Rectangle r = SwingUtilities.convertRectangle(ScrollPopupMenu.this, bounds, scrollPane);
scrollPane.getViewport().scrollRectToVisible(r);
});
}
@Override
public void menuKeyReleased(final MenuKeyEvent e) {
}
};
addMenuKeyListener(menuKeyListener);
}
private OverlayScrollPane createScrollPane() {
view = new JPanel(new BorderLayout());
view.add(this, BorderLayout.CENTER);
OverlayScrollPane overlayScrollPane =
new OverlayScrollPane(view, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
JScrollBar bar = overlayScrollPane.getVerticalScrollBar();
bar.putClientProperty("JScrollBar.thin", Boolean.TRUE);
DarkUIUtil.doNotCancelPopupSetup(bar);
DarkUIUtil.doNotCancelPopupSetup(overlayScrollPane.getScrollPane());
return overlayScrollPane;
} }
/** /**
@ -104,27 +58,10 @@ public class ScrollPopupMenu extends JPopupMenu {
this.maxHeight = maxHeight; this.maxHeight = maxHeight;
} }
@Override
public JMenuItem add(final JMenuItem menuItem) {
menuItem.getModel().addChangeListener(e -> contentPane.repaint(menuItem.getBounds()));
return super.add(menuItem);
}
protected void showPopup() { protected void showPopup() {
Component comp = getInvoker(); isVisible = true;
if (comp == null) return; popup = createPopup();
popup.show();
while (comp.getParent() != null) {
comp = comp.getParent();
}
if (popWin == null || popWin.getOwner() != comp) {
popWin = comp instanceof Window ? new JWindow((Window) comp) : new JWindow(new JFrame());
}
pack();
popWin.setLocation(posX, posY);
popWin.setVisible(true);
requestFocus();
} }
/** /**
@ -132,24 +69,19 @@ public class ScrollPopupMenu extends JPopupMenu {
* *
* @return scroll pane; * @return scroll pane;
*/ */
public JScrollPane getScrollPane() { public JScrollPane getScrollPane() {
return scrollPane; return popupMenuContainer.getScrollPane();
} }
@Override @Override
public boolean isVisible() { public boolean isVisible() {
return popWin != null && popWin.isShowing(); return isVisible;
} }
@Override @Override
public void setLocation(final int x, final int y) { public void setLocation(final int x, final int y) {
if (popWin != null && popWin.isShowing()) { posX = x;
popWin.setLocation(x, y); posY = y;
} else {
posX = x;
posY = y;
}
} }
@ -177,10 +109,11 @@ public class ScrollPopupMenu extends JPopupMenu {
} }
protected void hidePopup() { protected void hidePopup() {
if (popWin != null) { if (popup != null) {
firePopupMenuWillBecomeInvisible(); firePopupMenuWillBecomeInvisible();
popWin.setVisible(false); popup.hide();
popWin = null; isVisible = false;
popup = null;
firePropertyChange(PropertyKey.VISIBLE, Boolean.TRUE, Boolean.FALSE); firePropertyChange(PropertyKey.VISIBLE, Boolean.TRUE, Boolean.FALSE);
if (isPopupMenu()) { if (isPopupMenu()) {
MenuSelectionManager.defaultManager().clearSelectedPath(); MenuSelectionManager.defaultManager().clearSelectedPath();
@ -188,30 +121,12 @@ public class ScrollPopupMenu extends JPopupMenu {
} }
} }
private Popup createPopup() {
return popupMenuContainer.createPopup(this, posX, posY, maxHeight);
}
@Override @Override
public void pack() { public void pack() {
if (popWin == null) {
return;
}
final Dimension prefSize = getPreferredSize();
if (maxHeight <= 0 || prefSize.height <= maxHeight) {
setBounds(0, 0, prefSize.width, prefSize.height);
popWin.setContentPane(this);
setBorderPainted(true);
popWin.setSize(prefSize.width, prefSize.height);
} else {
int increment = getComponentCount() > 0
? Math.max(1, getComponent(0).getPreferredSize().height / 2)
: 1;
JScrollBar bar = scrollPane.getVerticalScrollBar();
bar.setValue(bar.getMinimum());
bar.setUnitIncrement(increment);
setBorderPainted(false);
view.add(this);
popWin.setContentPane(contentPane);
popWin.pack();
popWin.setSize(prefSize.width + bar.getPreferredSize().width, maxHeight);
}
} }
private boolean isPopupMenu() { private boolean isPopupMenu() {

4
core/src/main/java/com/github/weisj/darklaf/ui/combobox/DarkComboPopup.java

@ -24,6 +24,7 @@
package com.github.weisj.darklaf.ui.combobox; package com.github.weisj.darklaf.ui.combobox;
import com.github.weisj.darklaf.components.OverlayScrollPane; import com.github.weisj.darklaf.components.OverlayScrollPane;
import com.github.weisj.darklaf.ui.scrollpane.DarkScrollBarUI;
import javax.swing.*; import javax.swing.*;
import javax.swing.plaf.basic.BasicComboPopup; import javax.swing.plaf.basic.BasicComboPopup;
@ -93,7 +94,7 @@ public class DarkComboPopup extends BasicComboPopup {
protected JScrollPane createScroller() { protected JScrollPane createScroller() {
overlayScrollPane = new OverlayScrollPane(list, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, overlayScrollPane = new OverlayScrollPane(list, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
overlayScrollPane.getVerticalScrollBar().putClientProperty("JScrollBar.thin", Boolean.TRUE); overlayScrollPane.getVerticalScrollBar().putClientProperty(DarkScrollBarUI.KEY_SMALL, Boolean.TRUE);
return overlayScrollPane.getScrollPane(); return overlayScrollPane.getScrollPane();
} }
@ -110,7 +111,6 @@ public class DarkComboPopup extends BasicComboPopup {
setBorderPainted(true); setBorderPainted(true);
setOpaque(false); setOpaque(false);
add(overlayScrollPane); add(overlayScrollPane);
setDoubleBuffered(true);
setFocusable(false); setFocusable(false);
} }

1
core/src/main/java/com/github/weisj/darklaf/ui/popupmenu/DarkPopupMenuBorder.java

@ -42,7 +42,6 @@ public class DarkPopupMenuBorder extends MutableLineBorder implements UIResource
@Override @Override
public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width,
final int height) { final int height) {
setColor(UIManager.getDefaults().getColor("PopupMenu.borderColor"));
super.paintBorder(c, g, x, y, width, height); super.paintBorder(c, g, x, y, width, height);
} }

37
core/src/main/java/com/github/weisj/darklaf/ui/popupmenu/DarkPopupMenuUI.java

@ -23,7 +23,10 @@
*/ */
package com.github.weisj.darklaf.ui.popupmenu; package com.github.weisj.darklaf.ui.popupmenu;
import com.github.weisj.darklaf.components.OverlayScrollPane;
import com.github.weisj.darklaf.components.ScrollPopupMenu;
import com.github.weisj.darklaf.ui.DarkPopupFactory; import com.github.weisj.darklaf.ui.DarkPopupFactory;
import com.github.weisj.darklaf.util.DarkUIUtil;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
import javax.swing.*; import javax.swing.*;
@ -54,6 +57,7 @@ public class DarkPopupMenuUI extends BasicPopupMenuUI {
"doNotCancelPopup")); "doNotCancelPopup"));
public static final String KEY_DEFAULT_LIGHTWEIGHT_POPUPS = "PopupMenu.defaultLightWeightPopups"; public static final String KEY_DEFAULT_LIGHTWEIGHT_POPUPS = "PopupMenu.defaultLightWeightPopups";
protected static MouseGrabber mouseGrabber; protected static MouseGrabber mouseGrabber;
private PopupMenuContainer popupMenuContainer;
public static ComponentUI createUI(final JComponent x) { public static ComponentUI createUI(final JComponent x) {
return new DarkPopupMenuUI(); return new DarkPopupMenuUI();
@ -89,6 +93,9 @@ public class DarkPopupMenuUI extends BasicPopupMenuUI {
@Override @Override
public void installDefaults() { public void installDefaults() {
if (!(popupMenu instanceof ScrollPopupMenu)) {
popupMenuContainer = new PopupMenuContainer();
}
super.installDefaults(); super.installDefaults();
popupMenu.putClientProperty(DarkPopupFactory.KEY_START_HIDDEN, true); popupMenu.putClientProperty(DarkPopupFactory.KEY_START_HIDDEN, true);
} }
@ -102,6 +109,13 @@ public class DarkPopupMenuUI extends BasicPopupMenuUI {
} }
} }
@Override
public Popup getPopup(final JPopupMenu popup, final int x, final int y) {
if (popupMenuContainer == null) return super.getPopup(popup, x, y);
int maxHeight = DarkUIUtil.getScreenBounds(popup, x, y, false).height;
return popupMenuContainer.createPopup(popup, x, y, maxHeight);
}
/** /**
* This Method is responsible for removing the old MouseGrabber from the AppContext, to be able to add our own * This Method is responsible for removing the old MouseGrabber from the AppContext, to be able to add our own
* implementation for it that is a bit more generous with closing the popup. * implementation for it that is a bit more generous with closing the popup.
@ -110,7 +124,12 @@ public class DarkPopupMenuUI extends BasicPopupMenuUI {
MenuSelectionManager menuSelectionManager = MenuSelectionManager.defaultManager(); MenuSelectionManager menuSelectionManager = MenuSelectionManager.defaultManager();
ChangeListener mouseGrabber = null; ChangeListener mouseGrabber = null;
for (ChangeListener listener : menuSelectionManager.getChangeListeners()) { for (ChangeListener listener : menuSelectionManager.getChangeListeners()) {
if (listener.getClass().getEnclosingClass().getName().endsWith("BasicPopupMenuUI")) { if (listener == null) continue;
Class<?> listenerClass = listener.getClass();
if (listenerClass == null) continue;
Class<?> enclosingClass = listenerClass.getEnclosingClass();
if (enclosingClass == null) continue;
if (enclosingClass.getName().endsWith("BasicPopupMenuUI")) {
mouseGrabber = listener; mouseGrabber = listener;
break; break;
} }
@ -211,6 +230,22 @@ public class DarkPopupMenuUI extends BasicPopupMenuUI {
} }
lastPathSelected = p; lastPathSelected = p;
repaintIfNecessary(e);
}
protected void repaintIfNecessary(final ChangeEvent e) {
Object source = e.getSource();
if (source instanceof MenuSelectionManager) {
MenuSelectionManager manager = (MenuSelectionManager) source;
MenuElement[] path = manager.getSelectedPath();
if (path != null && path.length > 0) {
Component comp = path[0].getComponent();
if (comp.isVisible()) {
OverlayScrollPane sp = DarkUIUtil.getParentOfType(OverlayScrollPane.class, comp);
if (sp != null) sp.repaint(comp.getBounds());
}
}
}
} }
public void eventDispatched(final AWTEvent ev) { public void eventDispatched(final AWTEvent ev) {

139
core/src/main/java/com/github/weisj/darklaf/ui/popupmenu/PopupMenuContainer.java

@ -0,0 +1,139 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.weisj.darklaf.ui.popupmenu;
import com.github.weisj.darklaf.components.OverlayScrollPane;
import com.github.weisj.darklaf.decorators.PopupMenuAdapter;
import com.github.weisj.darklaf.ui.scrollpane.DarkScrollBarUI;
import com.github.weisj.darklaf.util.DarkUIUtil;
import javax.swing.*;
import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.*;
public class PopupMenuContainer extends JPanel {
private final JScrollPane scrollPane;
private final MenuKeyListener menuKeyListener;
private final PopupMenuListener menuListener;
private JPanel view;
private JPopupMenu popupMenu;
public PopupMenuContainer() {
super(new BorderLayout());
view = new JPanel(new BorderLayout());
OverlayScrollPane overlayScrollPane = createScrollPane(view);
scrollPane = overlayScrollPane.getScrollPane();
add(overlayScrollPane, BorderLayout.CENTER);
menuKeyListener = new MenuKeyListener() {
@Override
public void menuKeyTyped(final MenuKeyEvent e) {
}
@Override
public void menuKeyPressed(final MenuKeyEvent e) {
SwingUtilities.invokeLater(() -> {
if (popupMenu == null) return;
MenuElement[] path = e.getMenuSelectionManager().getSelectedPath();
if (path.length == 0) {
return;
}
Rectangle bounds = path[path.length - 1].getComponent().getBounds();
Rectangle r = SwingUtilities.convertRectangle(popupMenu, bounds, scrollPane);
scrollPane.getViewport().scrollRectToVisible(r);
});
}
@Override
public void menuKeyReleased(final MenuKeyEvent e) {
}
};
menuListener = new PopupMenuAdapter() {
@Override
public void popupMenuWillBecomeInvisible(final PopupMenuEvent e) {
onHide();
}
@Override
public void popupMenuCanceled(final PopupMenuEvent e) {
onHide();
}
private void onHide() {
if (popupMenu == null) return;
popupMenu.removePopupMenuListener(this);
popupMenu.removeMenuKeyListener(menuKeyListener);
}
};
}
public void setPopupMenu(final JPopupMenu popupMenu) {
this.popupMenu = popupMenu;
popupMenu.removeMenuKeyListener(menuKeyListener);
popupMenu.removePopupMenuListener(menuListener);
popupMenu.addMenuKeyListener(menuKeyListener);
popupMenu.addPopupMenuListener(menuListener);
}
public Popup createPopup(final JPopupMenu popupMenu, final int posX, final int posY, final int maxHeight) {
setPopupMenu(popupMenu);
final Dimension prefSize = popupMenu.getPreferredSize();
if (maxHeight <= 0 || prefSize.height <= maxHeight) {
setBounds(0, 0, prefSize.width, prefSize.height);
popupMenu.setBorderPainted(true);
return PopupFactory.getSharedInstance().getPopup(popupMenu.getInvoker(), popupMenu, posX, posY);
} else {
int increment = popupMenu.getComponentCount() > 0
? Math.max(1, popupMenu.getComponent(0).getPreferredSize().height / 2)
: 1;
JScrollBar bar = scrollPane.getVerticalScrollBar();
bar.setValue(bar.getMinimum());
bar.setUnitIncrement(increment);
view.removeAll();
view.add(popupMenu, BorderLayout.CENTER);
setBorder(popupMenu.getBorder());
popupMenu.setBorderPainted(false);
setPreferredSize(new Dimension(prefSize.width + bar.getPreferredSize().width, maxHeight));
return PopupFactory.getSharedInstance().getPopup(popupMenu.getInvoker(), this, posX, posY);
}
}
private OverlayScrollPane createScrollPane(final JComponent content) {
OverlayScrollPane overlayScrollPane =
new OverlayScrollPane(content, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
JScrollBar bar = overlayScrollPane.getVerticalScrollBar();
bar.putClientProperty(DarkScrollBarUI.KEY_SMALL, Boolean.TRUE);
DarkUIUtil.doNotCancelPopupSetup(bar);
DarkUIUtil.doNotCancelPopupSetup(overlayScrollPane.getScrollPane());
return overlayScrollPane;
}
public JScrollPane getScrollPane() {
return scrollPane;
}
}

4
core/src/main/java/com/github/weisj/darklaf/ui/scrollpane/DarkScrollBarUI.java

@ -73,8 +73,8 @@ public class DarkScrollBarUI extends BasicScrollBarUI implements ScrollBarConsta
thumbFadeStartColor = UIManager.getColor("ScrollBar.fadeStartColor"); thumbFadeStartColor = UIManager.getColor("ScrollBar.fadeStartColor");
thumbFadeEndColor = UIManager.getColor("ScrollBar.fadeEndColor"); thumbFadeEndColor = UIManager.getColor("ScrollBar.fadeEndColor");
trackBackground = UIManager.getColor("ScrollBar.trackColor"); trackBackground = UIManager.getColor("ScrollBar.trackColor");
smallSize = UIManager.getInt("ScrollBar.width"); smallSize = UIManager.getInt("ScrollBar.smallWidth");
size = UIManager.getInt("ScrollBar.smallWidth"); size = UIManager.getInt("ScrollBar.width");
} }
@Override @Override

32
core/src/main/java/com/github/weisj/darklaf/ui/tooltip/ToolTipUtil.java

@ -62,7 +62,7 @@ public class ToolTipUtil {
if (!context.isBestFit()) { if (!context.isBestFit()) {
return context.getToolTipLocation(p, null); return context.getToolTipLocation(p, null);
} }
Rectangle screenBounds = getScreenBounds(context.getTarget(), p); Rectangle screenBounds = DarkUIUtil.getScreenBounds(context.getTarget(), p);
Rectangle windowBounds = DarkUIUtil.getWindow(context.getTarget()).getBounds(); Rectangle windowBounds = DarkUIUtil.getWindow(context.getTarget()).getBounds();
Rectangle tooltipBounds = new Rectangle(); Rectangle tooltipBounds = new Rectangle();
tooltipBounds.setSize(context.getToolTip().getPreferredSize()); tooltipBounds.setSize(context.getToolTip().getPreferredSize());
@ -161,34 +161,4 @@ public class ToolTipUtil {
Point targetPos = target.getLocationOnScreen(); Point targetPos = target.getLocationOnScreen();
window.setLocation(targetPos.x + x, targetPos.y + y); window.setLocation(targetPos.x + x, targetPos.y + y);
} }
protected static Rectangle getScreenBounds(final JComponent target, final Point p) {
GraphicsConfiguration gc = getDrawingGC(p);
if (gc == null) {
gc = target.getGraphicsConfiguration();
}
Rectangle sBounds = gc.getBounds();
Insets screenInsets = Toolkit.getDefaultToolkit()
.getScreenInsets(gc);
// Take into account screen insets, decrease viewport
sBounds.x += screenInsets.left;
sBounds.y += screenInsets.top;
sBounds.width -= (screenInsets.left + screenInsets.right);
sBounds.height -= (screenInsets.top + screenInsets.bottom);
return sBounds;
}
private static GraphicsConfiguration getDrawingGC(final Point location) {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] devices = env.getScreenDevices();
for (GraphicsDevice device : devices) {
GraphicsConfiguration config = device.getDefaultConfiguration();
Rectangle rect = config.getBounds();
if (rect.contains(location)) {
return config;
}
}
return null;
}
} }

41
core/src/main/java/com/github/weisj/darklaf/util/DarkUIUtil.java

@ -464,6 +464,47 @@ public final class DarkUIUtil {
return p; return p;
} }
public static Rectangle getScreenBounds(final JComponent target, final Point p) {
return getScreenBounds(target, p.x, p.y);
}
public static Rectangle getScreenBounds(final JComponent target, final int x, final int y) {
return getScreenBounds(target, x, y, true);
}
public static Rectangle getScreenBounds(final JComponent target, final int x, final int y,
final boolean subtractInsets) {
GraphicsConfiguration gc = getDrawingGC(x, y);
if (gc == null) {
gc = target.getGraphicsConfiguration();
}
Rectangle sBounds = gc.getBounds();
if (subtractInsets) {
// Take into account screen insets, decrease viewport
Insets screenInsets = Toolkit.getDefaultToolkit()
.getScreenInsets(gc);
sBounds.x += screenInsets.left;
sBounds.y += screenInsets.top;
sBounds.width -= (screenInsets.left + screenInsets.right);
sBounds.height -= (screenInsets.top + screenInsets.bottom);
}
return sBounds;
}
private static GraphicsConfiguration getDrawingGC(final int x, final int y) {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] devices = env.getScreenDevices();
for (GraphicsDevice device : devices) {
GraphicsConfiguration config = device.getDefaultConfiguration();
Rectangle rect = config.getBounds();
if (rect.contains(x, y)) {
return config;
}
}
return null;
}
public enum Outline { public enum Outline {
error { error {
@Override @Override

Loading…
Cancel
Save