This question already has answers here:
How to move an image (animation)?
(2 answers)
Closed 6 years ago.
I am having trouble. I want to draw a rect onto my JPanel which is added to my JFrame contentPane. I want that x to be at a set pos but moving -x and restarting where +x begins. i.e. If I have a JPanel that is 800 x 400, I want the rext to take in those parameters but moving along the xaxis (x - Velx) repainting itself at 800 and continuing in the - x direction. I know this isn't sufficient info, none of my books that I have touch base on what I am trying to do so I lack proper terminology.
// Here is a good example of doing this
public class AnimatedBoat {
public static void main(String[] args) {
new AnimatedBoat();
}
public AnimatedBoat() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new AnimationPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class AnimationPane extends JPanel {
private BufferedImage boat;
private int xPos = 0;
private int direction = 1;
public AnimationPane() {
try {
boat = ImageIO.read(new File("boat.png"));
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
xPos += direction;
// change directions off window width
if (xPos + boat.getWidth() > getWidth()) {
xPos = getWidth() - boat.getWidth();
direction *= -1;
} else if (xPos < 0) {
xPos = 0;
direction *= -1;
}
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return boat == null ? super.getPreferredSize() : new Dimension(boat.getWidth() * 4, boat.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int y = getHeight() - boat.getHeight();
g.drawImage(boat, xPos, y, this);
}
}
}
sigh OK guys... There is going to be a painstaking amount of code here, but i'm going to do it anyway.
So basically, I have a custom made (well it's actually just a HEAVILY customized version of a JFrame) and am having major issues.
I have a background. (Fair enough, that's fine) THEN I have a Terminal frame that pops up and spits stuff out. This Terminal frame is based off another class named CustomFrame. I also have ANOTHER class called Notification, which is ALSO a frame class like Terminal ALSO based off Custom Frame.
In the beginning, background loads fine. Terminal loads fine. Calls method to show Notification window. And thats where the problem rises. The notification window won't show.
I have tried frame.setVisible(); frame.setSize(); frame.setLocation(); I have tried, EVERYTHING.
And if I don't show Terminal at all, it seems to spit it's code onto Notification instead, almost like there can only be ONE instance of the CustomFrame open AT ALL TIMES.
I hope you understand my problems... So here is the code!
Game.java
public class Game implements KeyListener {
int BACK_WIDTH = java.awt.Toolkit.getDefaultToolkit().getScreenSize().width;
int BACK_HEIGHT = java.awt.Toolkit.getDefaultToolkit().getScreenSize().height;
JFrame back_frame = new JFrame();
JPanel window = new JPanel();
JLabel title = new JLabel(Variables.TITLE);
Terminal login = new Terminal();
public static void main(String[] args) {
new Game();
}
public Game() {
try {
back_frame.setSize(BACK_WIDTH, BACK_HEIGHT);
back_frame.setLocation(0, 0);
back_frame.getContentPane().setBackground(Color.BLACK);
back_frame.setUndecorated(true);
back_frame.setVisible(true);
back_frame.add(window);
window.setBackground(Color.BLACK);
window.setLayout(null);
window.add(title);
title.setBounds((BACK_WIDTH / 2) - (550 / 2), (BACK_HEIGHT / 2) - (50 / 2), 550, 50);
title.setForeground(Color.WHITE);
back_frame.addKeyListener(this);
login.addKeyListener(this);
login.setLocationRelativeTo(null);
login.setVariables(Types.LOGINTERMINAL);
waitForStart();
} catch (FontFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
int index;
public void waitForStart() {
Timer timer = new Timer(2000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (index < 1 && index >= 0) {
index++;
} else {
((Timer)e.getSource()).stop();
login.setVisible(true);
login.slowPrint("Please login to continue...\n"
+ "Type 'help' for more information.\n");
}
}
});
timer.start();
}
public void keyPressed(KeyEvent e) {
int i = e.getKeyCode();
if(i == KeyEvent.VK_ESCAPE) {
System.exit(0);
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
CustomFrame.java
public class CustomFrame implements MouseListener {
static JFrame frame = new JFrame();
public static Paint window = new Paint();
public void addKeyListener(KeyListener listener) {
frame.addKeyListener(listener);
}
private Point initialClick;
private boolean inBounds = false;
public int getWidth() {
return frame.getWidth();
}
public int getHeight() {
return frame.getHeight();
}
public void add(JComponent component) {
window.add(component);
}
public void setLocation(int x, int y) {
frame.setLocation(x, y);
}
public void setLocationRelativeTo(Component c) {
frame.setLocationRelativeTo(c);
}
private void setFrameType(Types type) {
switch(type) {
case TERMINAL:
frame.setSize(600, 400);
break;
case LOGINTERMINAL:
frame.setSize(600, 400);
break;
case NOTIFICATION:
frame.setSize(300, 150);
break;
default:
frame.setSize(600, 400);
break;
}
}
int index = 0;
public void slowPrint(final String text, final JTextArea field) {
Timer timer = new Timer(40, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (index < text.length() && index >= 0) {
String newChar = Character.toString(text.charAt(index));
field.append(newChar);
index++;
} else {
field.append("\n");
index = 0;
((Timer)e.getSource()).stop();
}
}
});
timer.start();
}
public void slowPrintAndClear(final String text, final JTextArea field, final boolean andQuit) {
Timer timer = new Timer(40, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (index < text.length() && index >= 0) {
String newChar = Character.toString(text.charAt(index));
field.append(newChar);
index++;
} else {
field.append("\n");
if(andQuit == false) {
field.setText(null);
} else {
System.exit(0);
}
index = 0;
((Timer)e.getSource()).stop();
}
}
});
timer.start();
}
public CustomFrame(Types type) {
frame.setAlwaysOnTop(true);
frame.addMouseListener(this);
frame.setResizable(false);
frame.setUndecorated(true);
setFrameType(type);
frame.add(window);
window.setLayout(null);
frame.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
initialClick = e.getPoint();
frame.getComponentAt(initialClick);
}
});
frame.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
if(e.getX() >= 0 && e.getX()<= frame.getWidth() &&
e.getY() >= 0 && e.getY() <= 20) {
inBounds = true;
}
if(inBounds == true) {
int thisX = frame.getLocation().x;
int thisY = frame.getLocation().y;
int xMoved = (thisX + e.getX()) - (thisX + initialClick.x);
int yMoved = (thisY + e.getY()) - (thisY + initialClick.y);
int x = thisX + xMoved;
int y = thisY + yMoved;
frame.setLocation(x, y);
}
}
});
}
public JFrame setVisible(boolean bool) {
frame.setVisible(bool);
return null;
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
if(x >= CustomFrame.frame.getWidth() - 20 && x <= CustomFrame.frame.getWidth() - 6 &&
y >= 3 && y <= 14) {
frame.dispose();
}
}
public void mouseReleased(MouseEvent e) {
inBounds = false;
}
}
class Paint extends JPanel {
private static final long serialVersionUID = 1L;
private void doDrawing(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, CustomFrame.frame.getWidth(), CustomFrame.frame.getHeight());
Color LIGHT_BLUE = new Color(36, 171, 255);
//g2d.setColor(Color.BLUE);
GradientPaint topFill = new GradientPaint(0, 0, LIGHT_BLUE, CustomFrame.frame.getWidth(), 20, Color.BLUE);
g2d.setPaint(topFill);
g2d.fillRect(0, 0, CustomFrame.frame.getWidth(), 20);
g2d.setColor(Color.WHITE);
g2d.drawRect(0, 0, CustomFrame.frame.getWidth() - 1, CustomFrame.frame.getHeight() - 1);
g2d.drawLine(0, 20, CustomFrame.frame.getWidth(), 20);
g2d.fillRect(CustomFrame.frame.getWidth() - 20, 3, 14, 14);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
}
Terminal.java
public class Terminal implements KeyListener {
static CustomFrame frame = new CustomFrame(Types.TERMINAL);
JTextArea log = new JTextArea();
JTextField field = new JTextField();
public void setVisible(boolean bool) {
frame.setVisible(bool);
}
public void addKeyListener(KeyListener listener) {
frame.addKeyListener(listener);
}
public void setLogText(String str) {
log.setText(log.getText() + str + "\n");
}
public void setLocation(int x, int y) {
frame.setLocation(x, y);
}
public void setLocationRelativeTo(Component c) {
frame.setLocationRelativeTo(c);
}
int index = 0;
public void slowPrint(final String text) {
frame.slowPrint(text, log);
}
public void slowPrintAndClear(final String text, boolean andQuit) {
frame.slowPrintAndClear(text, log, andQuit);
}
public Terminal() {
try {
JScrollPane pane = new JScrollPane();
JScrollBar scrollBar = pane.getVerticalScrollBar();
scrollBar.setUI(new ScrollBarUI());
pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
pane.setViewportView(log);
frame.add(field);
frame.add(pane);
log.setBackground(Color.BLACK);
log.setForeground(Color.WHITE);
log.setWrapStyleWord(true);
log.setLineWrap(true);
pane.setBounds(4, 20 + 4, frame.getWidth() - 8, frame.getHeight() - 50);
pane.setBorder(null);
log.setEditable(false);
log.setCaretColor(Color.BLACK);
field.setBackground(Color.BLACK);
field.setForeground(Color.WHITE);
field.setBounds(2, frame.getHeight() - 23, frame.getWidth() - 5, 20);
field.setHighlighter(null);
field.setCaretColor(Color.BLACK);
field.addKeyListener(this);
field.setText(" > ");
} catch (FontFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void dumpToLog() {
log.setText(log.getText() + field.getText() + "\n");
field.setText(" > ");
}
public void setVariables(Types type) {
switch(type) {
case TERMINAL:
this.type = Types.TERMINAL;
break;
case LOGINTERMINAL:
this.type = Types.LOGINTERMINAL;
break;
default:
this.type = Types.TERMINAL;
break;
}
}
Types type;
public void keyPressed(KeyEvent e) {
int i = e.getKeyCode();
String text1 = " > ";
String text2 = field.getText().replaceFirst(text1, "");
String text2_1 = text2.trim();
String text = text1 + text2_1;
if (type == Types.TERMINAL) {
} else if (type == Types.LOGINTERMINAL) {
if(i == KeyEvent.VK_ENTER && field.isFocusOwner()) {
if(text.startsWith(" > register") || text.startsWith(" > REGISTER")) {
if(!(text.length() == 13)) {
dumpToLog();
slowPrint("Registry not available at this current given time.\n");
//TODO: Create registry system.
new Notification("test");
} else {
dumpToLog();
slowPrint("\nInformation:\n"
+ "Registers a new account.\n\n"
+ "Usage:\n"
+ "register <username>\n");
}
} else {
System.out.println("start |" + text + "| end");
dumpToLog();
slowPrint("Unknown command.\n");
}
}
} else {
// SETUP CODE FOR NOTIFICATION ERROR AGAIN
}
if(field.isFocusOwner() && i == KeyEvent.VK_LEFT || i == KeyEvent.VK_RIGHT) {
e.consume();
}
if(!field.getText().startsWith(" > ")) {
field.setText(" > ");
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
Notification.java
public class Notification {
static CustomFrame frame = new CustomFrame(Types.NOTIFICATION);
JTextArea display = new JTextArea();
public Notification(String notification) {
try {
frame.setLocationRelativeTo(null);
frame.add(display);
display.setBackground(Color.BLACK);
display.setForeground(Color.WHITE);
display.setWrapStyleWord(true);
display.setLineWrap(true);
display.setBounds(4, 20 + 4, frame.getWidth() - 8, frame.getHeight() - 50);
display.setBorder(null);
display.setEditable(false);
display.setCaretColor(Color.BLACK);
frame.slowPrint(notification, display);
frame.setVisible(true);
} catch (FontFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Types.java
public enum Types {
TERMINAL, LOGINTERMINAL,
NOTIFICATION;
}
ScrollBarUI.java
public class ScrollBarUI extends MetalScrollBarUI {
private Image thumb, track;
private JButton blankButton() {
JButton b = new JButton();
b.setPreferredSize(new Dimension(0, 0));
b.setMaximumSize(new Dimension(0, 0));
b.setMinimumSize(new Dimension(0, 0));
return b;
}
public ScrollBarUI() {
thumb = FauxImage.create(32, 32, true);
track = FauxImage.create(32, 32, false);
}
protected void paintThumb(Graphics g, JComponent component, Rectangle rectangle) {
Graphics2D g2d = (Graphics2D) g;
g.setColor(Color.BLUE);
g2d.drawImage(thumb, rectangle.x, rectangle.y, rectangle.width, rectangle.height, null);
g2d.setPaint(Color.WHITE);
g2d.drawRect(rectangle.x, rectangle.y, rectangle.width - 1, rectangle.height-1);
}
protected void paintTrack(Graphics g, JComponent component, Rectangle rectangle) {
((Graphics2D) g).drawImage(track, rectangle.x, rectangle.y, rectangle.width, rectangle.height, null);
}
protected JButton createIncreaseButton(int orientation) {
return blankButton();
}
protected JButton createDecreaseButton(int orientation) {
return blankButton();
}
private static class FauxImage {
static public Image create(int width, int height, boolean thumb) {
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bi.createGraphics();
if (thumb == true) {
Color LIGHT_BLUE = new Color(0, 140, 255);
//g2d.setPaint(Color.BLUE);
GradientPaint topFill = new GradientPaint(5, 25, Color.BLUE, 2, 2, LIGHT_BLUE);
g2d.setPaint(topFill);
g2d.fillRect(0, 0, width, height);
g2d.dispose();
} else {
g2d.setPaint(Color.BLACK);
g2d.fillRect(0, 0, width, height);
g2d.dispose();
}
return bi;
}
}
}
On a serious note though, if anyone is able to help me with such a sizeable post, I will SERIOUSLY be eternally grateful.
Cheers and thankyou... ALOT.
Edit:
Did have the time to fix up fonts. Extremely sorry, now it has been done.
Edit:
Here is where the Notification frame is called and doesn't end up showing:
if(!(text.length() == 13)) {
dumpToLog();
slowPrint("Registry not available at this current given time.\n");
//TODO: Create registry system.
new Notification("test");
}
As #Andrew Thompson, #trashgod pointed, it is a bad practice to use multiple frames.
If you still need to fix your problem, here goes:
The issue is with your static instance of the CustomFrame for your Game application and then modifying that frame instance using methods like setUndecorated(...).
In your Terminal class, you have
static CustomFrame frame = new CustomFrame(Types.TERMINAL);
and in your Notification class, you have
static CustomFrame frame = new CustomFrame(Types.NOTIFICATION);
but you are getting the same instance of the frame
static JFrame frame = new JFrame(); (in your CustomFrame class)
So what this means :
When the Game application loads, the Terminal is visible. And when you register a user, you are displying a Notification, with modified frame size and then by calling the setVisible() method of the CustomFrame.
Which is causing the issue. The setUndecorated() and setVisible() is invoked for the same static instance. YOU CANNOT MODIFY A FRAME WHICH IS VISIBLE. Meaning, YOU CAN ONLY MODIFY A FRAME BEFORE IT IS VISIBLE. Here your frame is already visible (for Terminal) and when displaying the Notification you are trying to change the size and display. WHICH IS WRONG.
As you said I want DIFFERENT JFrames, as in my code, I use Types.java as an enum to pick my different TYPES of frames. The frame is completely different each time due to the use of different components and sizing, to achieve this, you need multiple instances for each type of frame.
Changes/Fixes to your code :
Game1.java
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Game1 implements KeyListener
{
int BACK_WIDTH = java.awt.Toolkit.getDefaultToolkit().getScreenSize().width;
int BACK_HEIGHT = java.awt.Toolkit.getDefaultToolkit().getScreenSize().height;
JFrame back_frame = new JFrame();
JPanel window = new JPanel();
JLabel title = new JLabel("Title");
Terminal1 login = new Terminal1();
public static void main(String[] args)
{
new Game1();
}
public Game1()
{
try
{
back_frame.setSize(BACK_WIDTH, BACK_HEIGHT);
back_frame.setLocation(0, 0);
back_frame.getContentPane().setBackground(Color.BLACK);
back_frame.setUndecorated(true);
back_frame.setVisible(true);
back_frame.add(window);
window.setBackground(Color.BLACK);
window.setLayout(null);
window.add(title);
title.setBounds((BACK_WIDTH / 2) - (550 / 2), (BACK_HEIGHT / 2) - (50 / 2), 550, 50);
title.setForeground(Color.WHITE);
back_frame.addKeyListener(this);
login.addKeyListener(this);
login.setLocationRelativeTo(null);
login.setVariables(Types.LOGINTERMINAL);
waitForStart();
}
catch (Exception e)
{
e.printStackTrace();
}
}
int index;
public void waitForStart()
{
Timer timer = new Timer(2000, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (index < 1 && index >= 0)
{
index++;
}
else
{
((Timer) e.getSource()).stop();
login.setVisible(true);
login.slowPrint("Please login to continue...\n" + "Type 'help' for more information.\n");
}
}
});
timer.start();
}
public void keyPressed(KeyEvent e)
{
int i = e.getKeyCode();
if (i == KeyEvent.VK_ESCAPE)
{
System.exit(0);
}
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
}
}
CustomFrame1.java
import java.awt.Color;
import java.awt.Component;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.Timer;
public class CustomFrame1 implements MouseListener
{
JFrame frame = new JFrame();
public static Paint window = null;
public void addKeyListener(KeyListener listener)
{
frame.addKeyListener(listener);
}
private Point initialClick;
private boolean inBounds = false;
public int getWidth()
{
return frame.getWidth();
}
public int getHeight()
{
return frame.getHeight();
}
public void add(JComponent component)
{
window.add(component);
}
public void setLocation(int x, int y)
{
frame.setLocation(x, y);
}
public void setLocationRelativeTo(Component c)
{
frame.setLocationRelativeTo(c);
}
private void setFrameType(Types type)
{
switch (type)
{
case TERMINAL:
frame.setSize(600, 400);
break;
case LOGINTERMINAL:
frame.setSize(600, 400);
break;
case NOTIFICATION:
frame.setSize(300, 150);
break;
default:
frame.setSize(600, 400);
break;
}
}
int index = 0;
public void slowPrint(final String text, final JTextArea field)
{
Timer timer = new Timer(40, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (index < text.length() && index >= 0)
{
String newChar = Character.toString(text.charAt(index));
field.append(newChar);
index++;
}
else
{
field.append("\n");
index = 0;
((Timer) e.getSource()).stop();
}
}
});
timer.start();
}
public void slowPrintAndClear(final String text, final JTextArea field, final boolean andQuit)
{
Timer timer = new Timer(40, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (index < text.length() && index >= 0)
{
String newChar = Character.toString(text.charAt(index));
field.append(newChar);
index++;
}
else
{
field.append("\n");
if (andQuit == false)
{
field.setText(null);
}
else
{
System.exit(0);
}
index = 0;
((Timer) e.getSource()).stop();
}
}
});
timer.start();
}
public CustomFrame1(Types type)
{
window = new Paint(frame);
frame.setAlwaysOnTop(true);
frame.addMouseListener(this);
frame.setResizable(false);
frame.setUndecorated(true);
setFrameType(type);
frame.add(window);
window.setLayout(null);
frame.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
initialClick = e.getPoint();
frame.getComponentAt(initialClick);
}
});
frame.addMouseMotionListener(new MouseMotionAdapter()
{
public void mouseDragged(MouseEvent e)
{
if (e.getX() >= 0 && e.getX() <= frame.getWidth() && e.getY() >= 0 && e.getY() <= 20)
{
inBounds = true;
}
if (inBounds == true)
{
int thisX = frame.getLocation().x;
int thisY = frame.getLocation().y;
int xMoved = (thisX + e.getX()) - (thisX + initialClick.x);
int yMoved = (thisY + e.getY()) - (thisY + initialClick.y);
int x = thisX + xMoved;
int y = thisY + yMoved;
frame.setLocation(x, y);
}
}
});
}
public void dispose()
{
frame.dispose();
}
public JFrame setVisible(boolean bool)
{
frame.setVisible(bool);
return null;
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
int x = e.getX();
int y = e.getY();
if (x >= frame.getWidth() - 20 && x <= frame.getWidth() - 6 && y >= 3 && y <= 14)
{
frame.dispose();
}
}
public void mouseReleased(MouseEvent e)
{
inBounds = false;
}
}
class Paint extends JPanel
{
private static final long serialVersionUID = 1L;
private JFrame frame;
public Paint(JFrame frame)
{
this.frame = frame;
}
private void doDrawing(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, frame.getWidth(), frame.getHeight());
Color LIGHT_BLUE = new Color(36, 171, 255);
// g2d.setColor(Color.BLUE);
GradientPaint topFill = new GradientPaint(0, 0, LIGHT_BLUE, frame.getWidth(), 20, Color.BLUE);
g2d.setPaint(topFill);
g2d.fillRect(0, 0, frame.getWidth(), 20);
g2d.setColor(Color.WHITE);
g2d.drawRect(0, 0, frame.getWidth() - 1, frame.getHeight() - 1);
g2d.drawLine(0, 20, frame.getWidth(), 20);
g2d.fillRect(frame.getWidth() - 20, 3, 14, 14);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
doDrawing(g);
}
}
Terminal1.java
import java.awt.Color;
import java.awt.Component;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
public class Terminal1 implements KeyListener
{
static CustomFrame1 frame = new CustomFrame1(Types.TERMINAL);
JTextArea log = new JTextArea();
JTextField field = new JTextField();
public void setVisible(boolean bool)
{
frame.setVisible(bool);
}
public void addKeyListener(KeyListener listener)
{
frame.addKeyListener(listener);
}
public void setLogText(String str)
{
log.setText(log.getText() + str + "\n");
}
public void setLocation(int x, int y)
{
frame.setLocation(x, y);
}
public void setLocationRelativeTo(Component c)
{
frame.setLocationRelativeTo(c);
}
int index = 0;
public void slowPrint(final String text)
{
frame.slowPrint(text, log);
}
public void slowPrintAndClear(final String text, boolean andQuit)
{
frame.slowPrintAndClear(text, log, andQuit);
}
public Terminal1()
{
try
{
JScrollPane pane = new JScrollPane();
JScrollBar scrollBar = pane.getVerticalScrollBar();
scrollBar.setUI(new ScrollBarUI());
pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
pane.setViewportView(log);
frame.add(field);
frame.add(pane);
log.setBackground(Color.BLACK);
log.setForeground(Color.WHITE);
log.setWrapStyleWord(true);
log.setLineWrap(true);
pane.setBounds(4, 20 + 4, frame.getWidth() - 8, frame.getHeight() - 50);
pane.setBorder(null);
log.setEditable(false);
log.setCaretColor(Color.BLACK);
field.setBackground(Color.BLACK);
field.setForeground(Color.WHITE);
field.setBounds(2, frame.getHeight() - 23, frame.getWidth() - 5, 20);
field.setHighlighter(null);
field.setCaretColor(Color.BLACK);
field.addKeyListener(this);
field.setText(" > ");
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void dumpToLog()
{
log.setText(log.getText() + field.getText() + "\n");
field.setText(" > ");
}
public void setVariables(Types type)
{
switch (type)
{
case TERMINAL:
this.type = Types.TERMINAL;
break;
case LOGINTERMINAL:
this.type = Types.LOGINTERMINAL;
break;
default:
this.type = Types.TERMINAL;
break;
}
}
Types type;
public void keyPressed(KeyEvent e)
{
int i = e.getKeyCode();
String text1 = " > ";
String text2 = field.getText().replaceFirst(text1, "");
String text2_1 = text2.trim();
String text = text1 + text2_1;
if (type == Types.TERMINAL)
{
}
else if (type == Types.LOGINTERMINAL)
{
if (i == KeyEvent.VK_ENTER && field.isFocusOwner())
{
if (text.startsWith(" > register") || text.startsWith(" > REGISTER"))
{
if (!(text.length() == 13))
{
dumpToLog();
slowPrint("Registry not available at this current given time.\n");
// TODO: Create registry system.
new Notification1("test");
}
else
{
dumpToLog();
slowPrint("\nInformation:\n" + "Registers a new account.\n\n" + "Usage:\n" + "register <username>\n");
}
}
else
{
System.out.println("start |" + text + "| end");
dumpToLog();
slowPrint("Unknown command.\n");
}
}
}
else
{
// SETUP CODE FOR NOTIFICATION ERROR AGAIN
}
if (field.isFocusOwner() && i == KeyEvent.VK_LEFT || i == KeyEvent.VK_RIGHT)
{
e.consume();
}
if (!field.getText().startsWith(" > "))
{
field.setText(" > ");
}
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
}
}
Notification1.java
import java.awt.Color;
import javax.swing.JTextArea;
public class Notification1
{
static CustomFrame1 frame = new CustomFrame1(Types.NOTIFICATION);
JTextArea display = new JTextArea();
public Notification1(String notification)
{
try
{
frame.setLocationRelativeTo(null);
frame.add(display);
display.setBackground(Color.BLACK);
display.setForeground(Color.WHITE);
display.setWrapStyleWord(true);
display.setLineWrap(true);
display.setBounds(4, 20 + 4, frame.getWidth() - 8, frame.getHeight() - 50);
display.setBorder(null);
display.setEditable(false);
display.setCaretColor(Color.BLACK);
frame.slowPrint(notification, display);
frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
I am able to SWAP the panels but it is not good enough. For instance, if panel1 collides panel2, it swaps, but if the same collides panel3, panel3 also moves to panel1 location(which I don't want to happen). If there are about 10 panels, and if I want to swap panel1 with panel10 it is not possible with current logic. Can anyone please help me out.
Below is the code with the above logic:
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GDragAndDrop extends JFrame {
public GDragAndDrop() {
add(new op());
}
public static void main(String[] args) {
GDragAndDrop frame = new GDragAndDrop();
frame.setTitle("GDragAndDrop");
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);// Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class op extends JPanel implements MouseListener, MouseMotionListener {
JPanel p;
Point pPoint;
Point p1;
Point p2;
MouseEvent pressed;
JPanel[] panels = new JPanel[3];
public op() {
int b = 3;
int a = 0;
for (int i = 0; i < b; i++) {
panels[i] = new JPanel();
panels[i].setBackground(Color.cyan);
panels[i].setBorder(new LineBorder(Color.black));
a = a + 20;
panels[i].setPreferredSize(new Dimension(a, 400));
panels[i].addMouseListener(this);
panels[i].addMouseMotionListener(this);
panels[i].setBorder(new LineBorder(Color.black));
panels[i].setVisible(true);
panels[i].add("Center", new JLabel("To Move" + i));
this.add(panels[i]);
}
}
public JPanel getPanelColliding(JPanel dragPanel) {
Rectangle rDrag = dragPanel.getBounds();
for (int i = 0; i < 3; i++) {
if (panels[i] == dragPanel)
continue;
Rectangle r = panels[i].getBounds();
if (r.intersects(rDrag)) {
return panels[i];
}
}
return null;
}
public void mousePressed(MouseEvent e) {
int b = 3;
for (int i = 0; i < b; i++) {
if (e.getSource() == panels[i]) {
pressed = e;
p2 = panels[i].getLocation();
}
}
}
#Override
public void mouseDragged(MouseEvent arg0) {
int b = 3;
for (int i = 0; i < b; i++) {
if (arg0.getSource() == panels[i]) {
pPoint = panels[i].getLocation(pPoint);
int x = pPoint.x - pressed.getX() + arg0.getX();
int y = pPoint.y - pressed.getY() + arg0.getY();
if (getPanelColliding(panels[i]) != null) {
JPanel DragP = new JPanel();
DragP = getPanelColliding(panels[i]);
p1 = getPanelColliding(panels[i]).getLocation(p1);
int x1 = pPoint.x - pressed.getX() + arg0.getX();
int y1 = pPoint.y - pressed.getY() + arg0.getY();
panels[i].setLocation(x1, y1);
DragP.setLocation(p2);
} else
panels[i].setLocation(x, y);
}
}
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
}
}
If you don't want to use drag-and-drop, and if your JPanels are in columns, then consider these suggestions:
I've gotten this to work having the container JPanel (the one that holds the multiple column components) use a FlowLayout
I've added the MouseAdapter as a MouseListener and MouseMotionListener to the container JPanel, not the column components.
I obtained the selected column component by calling getComponentAt(mouseEvent.getPoint()) on the container JPanel. Of course check that it's not null.
If the selected component is not null, then I set a selectedComponent variable with this component, and put a placeholder JLabel that has the same preferredSize in its place. I do this by removing all components from the container JPanel, and then re-adding them all back except for the selected component where I instead add the placeholder JLabel. I then call revalidate and repaint on the container.
To drag the selected component, elevate it to the glassPane (i.e., add it to the glassPane).
make the glassPane visible and give it a null layout.
Drag the selected component in the glassPane simply by changing its location relative to the glassPane.
On mouseReleased, find out what column component the mouse is over, again by using getComponentAt(...).
Then remove all components from the container JPanel,
and then add them all back in the desired order.
Then again call revalidate and repaint on the container JPanel.
For example:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class SwapPanelEg extends JPanel {
private static final long serialVersionUID = 1594039652438249918L;
private static final int PREF_W = 400;
private static final int PREF_H = 400;
private static final int MAX_COLUMN_PANELS = 8;
private JPanel columnPanelsHolder = new JPanel();
public SwapPanelEg() {
columnPanelsHolder.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
for (int i = 0; i < MAX_COLUMN_PANELS; i++) {
int number = i + 1;
int width = 20 + i * 3;
int height = PREF_H - 30;
columnPanelsHolder.add(new ColumnPanel(number, width, height));
}
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
columnPanelsHolder.addMouseListener(myMouseAdapter);
columnPanelsHolder.addMouseMotionListener(myMouseAdapter);
setLayout(new GridBagLayout());
add(columnPanelsHolder);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private class MyMouseAdapter extends MouseAdapter {
private JComponent selectedPanel;
private Point deltaLocation;
private JLabel placeHolder = new JLabel();
private JComponent glassPane;
#Override
public void mousePressed(MouseEvent evt) {
if (evt.getButton() != MouseEvent.BUTTON1) {
return;
}
JPanel source = (JPanel) evt.getSource();
selectedPanel = (JComponent) source.getComponentAt(evt.getPoint());
if (selectedPanel == null) {
return;
}
if (selectedPanel == source) {
selectedPanel = null;
return;
}
glassPane = (JComponent) SwingUtilities.getRootPane(source).getGlassPane();
glassPane.setVisible(true);
Point glassPaneOnScreen = glassPane.getLocationOnScreen();
glassPane.setLayout(null);
Point ptOnScreen = evt.getLocationOnScreen();
Point panelLocOnScreen = selectedPanel.getLocationOnScreen();
int deltaX = ptOnScreen.x + glassPaneOnScreen.x - panelLocOnScreen.x;
int deltaY = ptOnScreen.y + glassPaneOnScreen.y - panelLocOnScreen.y;
deltaLocation = new Point(deltaX, deltaY);
Component[] allComps = source.getComponents();
for (Component component : allComps) {
source.remove(component);
if (component == selectedPanel) {
placeHolder.setPreferredSize(selectedPanel.getPreferredSize());
source.add(placeHolder);
selectedPanel.setSize(selectedPanel.getPreferredSize());
int x = ptOnScreen.x - deltaLocation.x;
int y = ptOnScreen.y - deltaLocation.y;
selectedPanel.setLocation(x, y);
glassPane.add(selectedPanel);
} else {
source.add(component);
}
}
revalidate();
repaint();
}
#Override
public void mouseDragged(MouseEvent evt) {
if (selectedPanel != null) {
Point ptOnScreen = evt.getLocationOnScreen();
int x = ptOnScreen.x - deltaLocation.x;
int y = ptOnScreen.y - deltaLocation.y;
selectedPanel.setLocation(x, y);
repaint();
}
}
#Override
public void mouseReleased(MouseEvent evt) {
if (evt.getButton() != MouseEvent.BUTTON1) {
return;
}
if (selectedPanel == null) {
return;
}
JComponent source = (JComponent) evt.getSource();
Component[] allComps = source.getComponents();
Component overComponent = (JComponent) source.getComponentAt(evt
.getPoint());
source.removeAll();
if (overComponent != null && overComponent != placeHolder
&& overComponent != source) {
for (Component component : allComps) {
if (component == placeHolder) {
source.add(overComponent);
} else if (component == overComponent) {
source.add(selectedPanel);
} else {
source.add(component);
}
}
} else {
for (Component component : allComps) {
if (component == placeHolder) {
source.add(selectedPanel);
} else {
source.add(component);
}
}
}
revalidate();
repaint();
selectedPanel = null;
}
}
private static void createAndShowGui() {
SwapPanelEg mainPanel = new SwapPanelEg();
JFrame frame = new JFrame("SwapPanelEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class ColumnPanel extends JPanel {
private static final long serialVersionUID = 5366233209639059032L;
private int number;
private int prefWidth;
private int prefHeight;
public ColumnPanel(int number, int prefWidth, int prefHeight) {
setName("ColumnPanel " + number);
this.number = number;
this.prefWidth = prefWidth;
this.prefHeight = prefHeight;
add(new JLabel(String.valueOf(number)));
setBorder(BorderFactory.createLineBorder(Color.black));
setBackground(Color.cyan);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(prefWidth, prefHeight);
}
public int getNumber() {
return number;
}
}
If you don't want to use Swing drag-and-drop, swap the content of the source and destination, as shown in this JLayeredPane example and variation.
Sorry if the title was vague but this is what I am trying to implement.
This is Battery Care software iconified / minimized. When you mouse over the icon, you get the window you see in the picture.
How can that be implemented in Java?
This uses a JPopupMenu to display information on a click, not the most recommended approach, as it's difficult to layout other components...but you could just as easily use a JWindow instead...
public class SystemTrayTest {
public static void main(String[] args) {
if (SystemTray.isSupported()) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
try {
final JPopupMenu popup = new JPopupMenu();
popup.add(new JLabel("Charging (45%)", JLabel.CENTER));
popup.add(new JLabel("Charging", new ImageIcon(ImageIO.read(SystemTrayTest.class.getResource("/battery_connection.png"))), JLabel.LEFT));
popup.add(new JLabel("Power Saver", new ImageIcon(ImageIO.read(SystemTrayTest.class.getResource("/flash_yellow.png"))), JLabel.LEFT));
popup.add(new JSeparator());
JMenuItem exitMI = new JMenuItem("Exit");
exitMI.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
popup.add(exitMI);
TrayIcon trayIcon = new TrayIcon(ImageIO.read(SystemTrayTest.class.getResource("/battery_green.png")), "Feel the power");
trayIcon.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
popup.setLocation(e.getX(), e.getY());
popup.setInvoker(popup);
popup.setVisible(true);
}
});
SystemTray.getSystemTray().add(trayIcon);
} catch (Exception ex) {
ex.printStackTrace();
System.exit(0);
}
}
});
}
}
}
Updated with mouse over support
Cause I can't resist playing...
public class SystemTrayTest {
public static void main(String[] args) {
new SystemTrayTest();
}
public SystemTrayTest() {
if (SystemTray.isSupported()) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
try {
TrayIcon trayIcon = new TrayIcon(ImageIO.read(SystemTrayTest.class.getResource("/battery_green.png")), "Feel the power");
MouseHandler mouseHandler = new MouseHandler();
trayIcon.addMouseMotionListener(mouseHandler);
trayIcon.addMouseListener(mouseHandler);
SystemTray.getSystemTray().add(trayIcon);
} catch (Exception ex) {
ex.printStackTrace();
System.exit(0);
}
}
});
}
}
public class MouseHandler extends MouseAdapter {
private Timer popupTimer;
private JWindow popup;
private Point point;
public MouseHandler() {
popup = new JWindow();
((JComponent)popup.getContentPane()).setBorder(new LineBorder(Color.LIGHT_GRAY));
popup.setLayout(new GridLayout(0, 1));
popup.add(new JLabel("Charging (45%)", JLabel.CENTER));
try {
popup.add(new JLabel("Charging", new ImageIcon(ImageIO.read(getClass().getResource("/battery_connection.png"))), JLabel.LEFT));
popup.add(new JLabel("Power Saver", new ImageIcon(ImageIO.read(getClass().getResource("/flash_yellow.png"))), JLabel.LEFT));
} catch (IOException exp) {
exp.printStackTrace();
}
popup.pack();
popupTimer = new Timer(250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (point != null) {
System.out.println(point);
Rectangle bounds = getScreenViewableBounds(point);
int x = point.x;
int y = point.y;
if (y < bounds.y) {
y = bounds.y;
} else if (y > bounds.y + bounds.height) {
y = bounds.y + bounds.height;
}
if (x < bounds.x) {
x = bounds.x;
} else if (x > bounds.x + bounds.width) {
x = bounds.x + bounds.width;
}
if (x + popup.getWidth() > bounds.x + bounds.width) {
x = (bounds.x + bounds.width) - popup.getWidth();
}
if (y + popup.getWidth() > bounds.y + bounds.height) {
y = (bounds.y + bounds.height) - popup.getHeight();
}
popup.setLocation(x, y);
popup.setVisible(true);
}
}
});
popupTimer.setRepeats(false);
}
#Override
public void mouseExited(MouseEvent e) {
System.out.println("Stop");
point = null;
popupTimer.stop();
popup.setVisible(false);
}
#Override
public void mouseMoved(MouseEvent e) {
popupTimer.restart();
point = e.getPoint();
}
#Override
public void mouseClicked(MouseEvent e) {
System.exit(0);
}
}
public static GraphicsDevice getGraphicsDeviceAt(Point pos) {
GraphicsDevice device = null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice lstGDs[] = ge.getScreenDevices();
ArrayList<GraphicsDevice> lstDevices = new ArrayList<GraphicsDevice>(lstGDs.length);
for (GraphicsDevice gd : lstGDs) {
GraphicsConfiguration gc = gd.getDefaultConfiguration();
Rectangle screenBounds = gc.getBounds();
if (screenBounds.contains(pos)) {
lstDevices.add(gd);
}
}
if (lstDevices.size() == 1) {
device = lstDevices.get(0);
}
return device;
}
public static Rectangle getScreenViewableBounds(Point p) {
return getScreenViewableBounds(getGraphicsDeviceAt(p));
}
public static Rectangle getScreenViewableBounds(GraphicsDevice gd) {
Rectangle bounds = new Rectangle(0, 0, 0, 0);
if (gd != null) {
GraphicsConfiguration gc = gd.getDefaultConfiguration();
bounds = gc.getBounds();
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
bounds.x += insets.left;
bounds.y += insets.top;
bounds.width -= (insets.left + insets.right);
bounds.height -= (insets.top + insets.bottom);
}
return bounds;
}
}
At first, I thought this would be fairly trivial - add a mouse listener to the TrayIcon using addMouseListener() and use the mouseEntered() and mouseExitedEvents():
icon.addMouseListener(new MouseAdapter()
{
#Override
public void mouseEntered(MouseEvent e)
{
System.out.println("Mouse over icon");
}
#Override
public void mouseExited(MouseEvent e)
{
System.out.println("Mouse leaving icon");
}
});
But, at least on the platform I tested with (Java 7u10 on Windows) this did not work - no events were generated when I hovered the mouse cursor over the tray icon. What did work was a MouseMotionListener and the addMouseMotionListener method:
icon.addMouseMotionListener(new MouseMotionAdapter()
{
#Override
public void mouseMoved(MouseEvent e)
{
System.out.println("Moving...");
}
});
Events are generated in mouseMoved() only when the mouse is over the icon. With a bit of work, this could be used to display a JWindow after a certain delay after first event is received to emulate tooltip time (you can get the platform's tooltip display time through something like ToolTipManager.sharedInstance().getInitialDelay().