Many custom Swing components are made of JPanel. Sometimes these components are required to be selectable.
How is it possible to make JPanel look selected? It should be selected like other items do, like menu items, or JTable cells. I.e. entire JPanel should be covered with transparent blue. It would be excellent, if this would made exactly like other items in L&F / theme,
Is it possible?
You could consider taking a look at JXLayer/JLayer, which would allow you to paint an overlay on top the component.
import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.jdesktop.jxlayer.JXLayer;
import org.jdesktop.jxlayer.QualityHints;
import org.jdesktop.jxlayer.plaf.AbstractBufferedLayerUI;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
SelectablePane pane = new SelectablePane();
SelectableUI ui = new SelectableUI();
JXLayer<JPanel> layer = new JXLayer<>(pane, ui);
layer.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
ui.setSelected(!ui.isSelected());
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(layer);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class SelectablePane extends JPanel {
public SelectablePane() {
setLayout(new GridBagLayout());
add(new JLabel("Hello world"));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public static class SelectableUI extends AbstractBufferedLayerUI<JPanel> {
public static Map<RenderingHints.Key, Object> mapRenderHints = new QualityHints();
private boolean selected = false;
public SelectableUI() {
mapRenderHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); // okay
mapRenderHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // bad
mapRenderHints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); // okay
mapRenderHints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
mapRenderHints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
mapRenderHints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
mapRenderHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
}
public void setSelected(boolean value) {
if (selected != value) {
selected = value;
firePropertyChange("selected", !selected, selected);
repaint();
}
}
public boolean isSelected() {
return selected;
}
#Override
protected void paintLayer(Graphics2D g2, JXLayer<? extends JPanel> l) {
super.paintLayer(g2, l);
if (isSelected()) {
Graphics2D g2d = (Graphics2D) g2.create();
g2d.setColor(UIManager.getColor("List.selectionBackground"));
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
g2d.fillRect(0, 0, l.getWidth(), l.getHeight());
g2d.dispose();
}
}
#Override
protected Map<RenderingHints.Key, Object> getRenderingHints(JXLayer<? extends JPanel> l) {
return mapRenderHints;
}
public void repaint() {
setDirty(true);
}
public void invalidate() {
setDirty(true);
}
public void revalidate() {
setDirty(true);
}
}
}
Related
In the example below there is a standard way to trigger drag and drop, which is mousePress+mouseMove.
import javax.swing.*;
import java.awt.datatransfer.StringSelection;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
public class DndExample extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new DndExample());
}
public DndExample() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel dragLabel = createDndLabel();
getContentPane().add(dragLabel);
pack();
setVisible(true);
}
private JLabel createDndLabel() {
JLabel label = new JLabel("Drag me, please");
DragGestureListener dragGestureListener = (dragTrigger) -> {
dragTrigger.startDrag(null, new StringSelection(label.getText()));
};
DragSource dragSource = DragSource.getDefaultDragSource();
dragSource.createDefaultDragGestureRecognizer(label, DnDConstants.ACTION_COPY, dragGestureListener);
return label;
}
}
Is it possible to trigger startDrag on mousePressed without mouseMove? The desired behaviour is something like that: I press the mouse button then cursor changes indicating that drag has started, if mouse is moved than drag is continued. I obviously know that I may add MouseListener and change cursor manually but there is much more code needed to restore previous cursor.
Because you're asking for non-standard behaviour, you're going to need to do the "extra" lifting yourself, this requires you to have a MouseListener with mousePressed setting the cursor and mouseReleased resting it (so if the user just clicks and doesn't drag the component, you don't end up with a stupid cursor state) and the DragGestureListener#dragDropEnd also resetting the cursor.
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
import javax.swing.border.MatteBorder;
public class DragAndDropTest {
public static void main(String[] args) {
new DragAndDropTest();
}
public DragAndDropTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridLayout(1, 2));
add(new DropPane());
add(new DragPane());
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class DragPane extends JPanel {
private DragSource ds;
private Transferable transferable;
public DragPane() {
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
#Override
public void mouseReleased(MouseEvent e) {
setCursor(Cursor.getDefaultCursor());
}
});
ds = new DragSource();
transferable = new Transferable() {
#Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{DataFlavor.stringFlavor};
}
#Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return DataFlavor.stringFlavor.equals(flavor);
}
#Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
return "This is a test";
}
};
ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, new DragGestureListener() {
#Override
public void dragGestureRecognized(DragGestureEvent dge) {
// This is where you would export the data you want
// to transfer
ds.startDrag(dge, Cursor.getPredefinedCursor(Cursor.HAND_CURSOR), transferable, new DragSourceListener() {
#Override
public void dragEnter(DragSourceDragEvent dsde) {
}
#Override
public void dragOver(DragSourceDragEvent dsde) {
}
#Override
public void dropActionChanged(DragSourceDragEvent dsde) {
}
#Override
public void dragExit(DragSourceEvent dse) {
}
#Override
public void dragDropEnd(DragSourceDropEvent dsde) {
setCursor(Cursor.getDefaultCursor());
}
});
}
});
setLayout(new GridBagLayout());
add(new JLabel("Drag from here"));
setBorder(new LineBorder(Color.RED));
}
}
public class DropPane extends JPanel {
private List<Point> dropPoints;
public DropPane() {
dropPoints = new ArrayList<>(25);
setDropTarget(new DropTarget(this, new DropTargetListener() {
#Override
public void dragEnter(DropTargetDragEvent dtde) {
}
#Override
public void dragOver(DropTargetDragEvent dtde) {
}
#Override
public void dropActionChanged(DropTargetDragEvent dtde) {
}
#Override
public void dragExit(DropTargetEvent dte) {
}
#Override
public void drop(DropTargetDropEvent dtde) {
// Normally here, I'd inspect the Transferable and make sure
// what is been dropped and can be imported, I'd then go through
// the process of unwrapping the data from the Transferable and
// processing it appropriatly, but in this example, I really don't
// care, I just care about WHERE the event occured
dropPoints.add(dtde.getLocation());
dtde.dropComplete(true);
repaint();
}
}));
setLayout(new GridBagLayout());
add(new JLabel("Drop to here"));
setBorder(new MatteBorder(1, 1, 1, 0, Color.RED));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
for (Point p : dropPoints) {
g.fillOval(p.x - 2, p.y - 2, 5, 5);
}
}
}
}
Now, remember, you're doing something the system doesn't want you to do, so it might turn around and byte you any way
I might consider writing a factory method which took a reference to Component, Transferable (and probably a Cursor) and build and registered the MouseListener and DragSource
How would I go and add an image on the mouse coordinates when the mouse clicks? I have looked at this :Adding Images on Mouse Click to JPanel
But I don't understand it and am trying to add it on mouse click in an applet
And please don't say, "Learn some basic java first! and provide me with a link to some oracle docs", I just can't get any info from those things.
Code:
> `import java.applet.Applet;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
`import java.net.URL;
import javax.imageio.ImageIO;
public class SHR extends Applet implements MouseListener{
int a;
int b;
#Override
public void mouseClicked(MouseEvent e) {
a = e.getX();
b = e.getY();
paint(null, a, b);/this is the part i am having trouble with
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
public void paint(Graphics g, int x, int y){
BufferedImage photo = null;
try
{
URL u = new URL(getCodeBase(),"SilverHandRecruit.png");
photo = ImageIO.read(u);
}
catch (IOException e)
{
g.drawString("Problem reading the file", 100, 100);
}
g.drawImage(photo,x, y, 10, 30, null);
}
}
`
The problem is, I don't know what I am supposed to replace "null" with to get it to work
Thanks
Start by taking a look at Painting in AWT and Swing and Performing Custom Painting to understand how painting works in AWT/Swing.
Then, take a look at 2D Graphics for more details about how you can use the Graphics class to paint things with.
This is a really basic example which loads a single image and every time you click on the panel, moves it to that point.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DrawImage {
public static void main(String[] args) {
new DrawImage();
}
public DrawImage() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage image;
private Point drawPoint;
public TestPane() {
try {
image = ImageIO.read(getClass().getResource("/SmallPony.png"));
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
drawPoint = new Point(e.getPoint());
repaint();
}
});
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (drawPoint != null) {
g2d.drawImage(image, drawPoint.x, drawPoint.y, this);
}
g2d.dispose();
}
}
}
I am trying to create a graphics drawing program that allows the user to draw red pixels on the screen by dragging their mouse over it. So in a way, you can think of this program as Microsoft's Paint program but with only the pencil drawing tool and color red.
Unfortunately the mouseDragged() function in my program is not working properly. It will skip some of the pixels on the screen if I move my mouse too fast, like this:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FrameView extends JFrame {
JPanel panel;
Graphics2D drawingContext;
public static void main(String[] args) {
new FrameView();
}
public FrameView() {
panel = new JPanel();
panel.addMouseMotionListener(new MouseControls());
panel.setBackground(Color.WHITE);
this.add(panel);
this.setSize(new Dimension(500, 500));
this.setTitle("Drawing Program");
this.setVisible(true);
drawingContext = (Graphics2D)panel.getGraphics();
}
private class MouseControls extends MouseAdapter {
#Override
public void mouseDragged(MouseEvent e) {
int x = e.getX();
int y = e.getY();
final int WIDTH = 1;
final int HEIGHT = 1;
Shape pixel = new Rectangle(x, y, WIDTH, HEIGHT);
drawingContext.setColor(Color.RED);
drawingContext.draw(pixel);
}
}
}
getGraphics is NOT how painting works in Swing, instead, you should be overriding the paintComponent method of the component and performing your custom painting there.
Painting is destructive, it is expected that when ever paintComponent is called, you will completely repaint the current state of the component.
Have a look at Painting in AWT and Swing and Performing Custom Painting for more details
As to you "mouse" problem, this is actually how it works, you won't be notified of EVERY pixel position the mouse has to pass through, your mouse would lag horribly across the screen if it did. Instead, the OS moves the mouse in ever increasing steps based on the speed of the movement of the user input.
Instead of drawing just the points, draw lines between them, for example
nb: I've deliberately painted the points larger so you can see where they are been reported, you will see that all the dots (for a single drag) are connected
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private List<List<Point>> points = new ArrayList<>(25);
private List<Point> activeList;
public TestPane() {
MouseAdapter ma = new MouseAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
if (activeList != null) {
activeList.add(e.getPoint());
repaint();
}
}
#Override
public void mousePressed(MouseEvent e) {
activeList = new ArrayList<>(25);
points.add(activeList);
}
#Override
public void mouseReleased(MouseEvent e) {
if (activeList != null && activeList.isEmpty()) {
points.remove(activeList);
}
activeList = null;
}
};
addMouseMotionListener(ma);
addMouseListener(ma);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
for (List<Point> group : points) {
Point previous = null;
for (Point p : group) {
// You can get rid of this, it's simply to show
// where the points would actually be rendered
g2d.fill(new Ellipse2D.Float(p.x - 2, p.y - 2, 4, 4));
if (previous != null) {
g2d.draw(new Line2D.Float(previous, p));
}
previous = p;
}
}
g2d.dispose();
}
}
}
I am working on Java Game Development Tutorials given on buckysroom.org. I am creating a Screen class, which allows me to go full screen. Then, when I try to paint it with text, the screen does not appear, and only the text is shown on my working window (Eclipse) If I comment out the paint method or make it paintComponent, the red screen appears, but without any text. Can anyone help me on how to deal with this?
The Screen class:
import java.awt.*;
import javax.swing.JFrame;
public class Screen {
private GraphicsDevice vc;
public Screen() {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
vc = env.getDefaultScreenDevice();
}
public void setFullScreen(DisplayMode dm, JFrame window) {
window.setUndecorated(true);
window.setResizable(false);
vc.setFullScreenWindow(window);
if (dm != null && vc.isDisplayChangeSupported()) {
try {
vc.setDisplayMode(dm);
} catch (Exception ex) {
}
}
}
public Window getFullScreenWindow() {
return vc.getFullScreenWindow();
}
public void restoreScreen() {
Window w = vc.getFullScreenWindow();
if (w != null) {
w.dispose();
}
vc.setFullScreenWindow(null);
}
}
This is the class where I call it:
import java.awt.*;
import javax.swing.JFrame;
public class bucky extends JFrame {
public static void main(String[] args) {
DisplayMode dm = new DisplayMode(800, 600, 16, DisplayMode.REFRESH_RATE_UNKNOWN);
bucky m = new bucky();
m.run(dm);
}
public void run(DisplayMode dm) {
this.getContentPane().setBackground(Color.RED);
setForeground(Color.BLACK);
setFont(new Font("Arial", Font.PLAIN, 24));
Screen s = new Screen();
try {
s.setFullScreen(dm, this);
try {
Thread.sleep(5000);
} catch (Exception ex) {
}
} finally {
s.restoreScreen();
}
}
public void paint(Graphics g) {
g.drawString("This is awesome", 200, 200);
}
}
My suspicion is that the Thread.sleep is cause the Event Dispatching Thread to be put to sleep, preventing it from processing any paint events (or any other kind of events for that matter) and/or the paint method of the JFrame is not an appropriate method for performing paint in (generally it's not for a number of reasons)...
Instead, you should consider using something like javax.swing.Timer which you can use to set up an alarm for some time in the future and it will call you back.
You should also consider using something like a JPanel to perform your custom painting on, for example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FullScreenTest {
public static void main(String[] args) {
new FullScreenTest();
}
public FullScreenTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new TestPane());
DisplayMode dm = new DisplayMode(800, 600, 16, DisplayMode.REFRESH_RATE_UNKNOWN);
Screen.setFullScreen(null, frame);
Timer timer = new Timer(5000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Screen.restoreScreen();
}
});
timer.start();
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setFont(new Font("Arial", Font.PLAIN, 24));
setBackground(Color.RED);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g.drawString("This is awesome", 200, 200);
g2d.dispose();
}
}
public static class Screen {
public static GraphicsDevice getGraphicsDevice() {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
return env.getDefaultScreenDevice();
}
public static void setFullScreen(DisplayMode dm, JFrame window) {
window.setUndecorated(true);
window.setResizable(false);
GraphicsDevice gd = getGraphicsDevice();
gd.setFullScreenWindow(window);
if (dm != null && gd.isDisplayChangeSupported()) {
try {
gd.setDisplayMode(dm);
} catch (Exception ex) {
}
}
}
public static Window getFullScreenWindow() {
GraphicsDevice gd = getGraphicsDevice();
return gd.getFullScreenWindow();
}
public static void restoreScreen() {
GraphicsDevice gd = getGraphicsDevice();
Window w = gd.getFullScreenWindow();
if (w != null) {
w.dispose();
}
gd.setFullScreenWindow(null);
}
}
}
Take a look at:
Concurrency in Swing
How to Use Swing Timers
Performing Custom Painting
For more details...
Also, because of the type of work it's doing, Screen could also be a fully static class. It maintains no contextual information and simply provides utility functionality - IMHO.
If you needed one for each GraphicsDevice, that would be another story ;)
Java Glass pane auto resize when I resize the whole interface,but I want to make it stick to a specific location, it will look like this:
Instead of moving around when I resize it.
Thanks
There's a number of ways this might be achieved, but the basic requirement will require some kind of reference to the component your glass pane content is trying to stick to. This means that when the components are updated and are required to be laid out, you can find the location of the sticky component and update the position of the content on the glass pane.
Remember, the glass pane is a container which occupies the entire content are of a window, it's what's contained within the glass pane that you need to update
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class StickyGlassPaneExample {
public static void main(String[] args) {
new StickyGlassPaneExample();
}
public StickyGlassPaneExample() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
StickyGlassPane stickyGlassPane = new StickyGlassPane();
TestPane testPane = new TestPane(stickyGlassPane);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(testPane);
frame.setSize(600, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setGlassPane(stickyGlassPane);
stickyGlassPane.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private List<JTextField> fields;
public TestPane(StickyGlassPane stickyGlassPane) {
fields = new ArrayList<JTextField>(100);
for (int index = 0; index < 100; index++) {
JTextField field = new JTextField(10);
fields.add(field);
add(field);
}
int fieldIndex = (int)(Math.random() * (fields.size() - 1));
JTextField sticky = fields.get(fieldIndex);
sticky.setText("Sticky");
stickyGlassPane.setStickyComponent(sticky);
}
}
public class StickyGlassPane extends JPanel {
private Component component;
private JPanel overlay;
public StickyGlassPane() {
setOpaque(false);
overlay = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
g2d.drawRect(0, 0, getWidth(), getHeight());
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
g2d.fillRect(0, 0, getWidth(), getHeight());
}
};
overlay.setOpaque(false);
add(overlay);
}
#Override
public void doLayout() {
if (component != null) {
Point p = component.getLocation();
SwingUtilities.convertPoint(component, p, this);
overlay.setLocation(p);
overlay.setSize(component.getSize());
} else {
overlay.setBounds(0, 0, 0, 0);
}
}
public void setStickyComponent(Component component) {
this.component = component;
revalidate();
}
}
}