I am working on a Music Player
I am using a JSlider as seek bar and using a JLabel to draw text on screen, such as song name.
I am new to Graphics2D
Here's the minimized code:
public class JSliderDemo extends JFrame
{
JLabel label;
JSlider seek = new JSlider();
int y = 10;
public JSliderDemo()
{
setSize(400, 400);
setLocationRelativeTo(null);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
createWindow();
setVisible(true);
startThread();
}
public void createWindow()
{
JPanel panel = new JPanel(null);
panel.setOpaque(true);
panel.setBackground(Color.BLUE);
label = new Component();
label.setSize(400, 400);
label.setLocation(0, 0);
createSlider();
panel.add(seek);
panel.add(label);
add(panel);
}
protected void createSlider()
{
seek.setUI(new SeekBar(seek, 300, 10, new Dimension(20, 20), 5,
Color.DARK_GRAY, Color.RED, Color.RED));
seek.setOrientation(JProgressBar.HORIZONTAL);
seek.setOpaque(false);
seek.setLocation(10, 50);
seek.setSize(300, 20);
seek.setMajorTickSpacing(0);
seek.setMinorTickSpacing(0);
seek.setMinimum(0);
seek.setMaximum(1000);
}
protected void startThread()
{
Thread thread = new Thread(new Runnable(){
#Override
public void run()
{
try
{
while(true)
{
if(y == label.getHeight()){y = 1;}
label.repaint();
y += 1;
Thread.sleep(100);
}
}
catch(Exception ex){}
}
});
thread.start();
}
protected class Component extends JLabel
{
#Override
public void paintComponent(Graphics g)
{
Graphics2D gr = (Graphics2D) g;
gr.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gr.setColor(Color.RED);
gr.setFont(new Font("Calibri", Font.PLAIN, 16));
gr.drawString("Slider", 50, y);
}
}
public static void main(String[] args)
{
new JSliderDemo();
}
}
The Custom Slider UI class prints a line each time the JSlider is repainted.
Through this, I was able to find out that, when I call repaint() for JLabel it automatically repaints JSlider with it even though JSlider is not included in JLabel.
Output :
Slider re-painted
Slider re-painted
Slider re-painted
Slider re-painted
Slider re-painted
Slider re-painted.........
Now if I remove label.repaint() from the Thread, then the JSlider is not re-painted.
Output:
Slider re-painted
Slider re-painted
Is the repaint() method supposed to work like this?
Here's the Custom Slider UI class :
package jsliderdemo;
import java.awt.*;
import javax.swing.*;
import java.awt.geom.RoundRectangle2D;
import javax.swing.plaf.basic.BasicSliderUI;
public class SeekBar extends BasicSliderUI
{
private int TRACK_ARC = 5;
private int TRACK_WIDTH = 8;
private int TRACK_HEIGHT = 8;
private Color backGround = Color.GRAY;
private Color trackColor = Color.RED;
private Color thumbColor = Color.WHITE;
private Dimension THUMB_SIZE = new Dimension(20, 20);
private final RoundRectangle2D.Float trackShape = new RoundRectangle2D.Float();
public SeekBar(final JSlider b, int width, int height, Dimension thumbSize, int arc,
Color backGround, Color trackColor, Color thumbColor)
{
super(b);
this.TRACK_ARC = arc;
this.TRACK_WIDTH = width;
this.TRACK_HEIGHT = height;
this.THUMB_SIZE = thumbSize;
this.backGround = backGround;
this.trackColor = trackColor;
this.thumbColor = thumbColor;
}
#Override
protected void calculateTrackRect()
{
super.calculateTrackRect();
if (isHorizontal())
{
trackRect.y = trackRect.y + (trackRect.height - TRACK_HEIGHT) / 2;
trackRect.height = TRACK_HEIGHT;
}
else
{
trackRect.x = trackRect.x + (trackRect.width - TRACK_WIDTH) / 2;
trackRect.width = TRACK_WIDTH;
}
trackShape.setRoundRect(trackRect.x, trackRect.y, trackRect.width, trackRect.height, TRACK_ARC, TRACK_ARC);
}
#Override
protected void calculateThumbLocation()
{
super.calculateThumbLocation();
if (isHorizontal())
{
thumbRect.y = trackRect.y + (trackRect.height - thumbRect.height) / 2;
}
else
{
thumbRect.x = trackRect.x + (trackRect.width - thumbRect.width) / 2;
}
}
#Override
protected Dimension getThumbSize()
{
return THUMB_SIZE;
}
private boolean isHorizontal()
{
return slider.getOrientation() == JSlider.HORIZONTAL;
}
#Override
public void paint(final Graphics g, final JComponent c)
{
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
super.paint(g, c);
}
#Override
public void paintTrack(final Graphics g)
{
System.out.println("Slider re-painted");
Graphics2D g2 = (Graphics2D) g;
Shape clip = g2.getClip();
boolean horizontal = isHorizontal();
boolean inverted = slider.getInverted();
// Paint shadow.
//g2.setColor(new Color(170, 170 ,170));
//g2.fill(trackShape);
// Paint track background.
g2.setColor(backGround);
g2.setClip(trackShape);
trackShape.y += 1;
g2.fill(trackShape);
trackShape.y = trackRect.y;
g2.setClip(clip);
// Paint selected track.
if (horizontal)
{
boolean ltr = slider.getComponentOrientation().isLeftToRight();
if (ltr) inverted = !inverted;
int thumbPos = thumbRect.x + thumbRect.width / 2;
if (inverted)
{
g2.clipRect(0, 0, thumbPos, slider.getHeight());
}
else
{
g2.clipRect(thumbPos, 0, slider.getWidth() - thumbPos, slider.getHeight());
}
}
else
{
int thumbPos = thumbRect.y + thumbRect.height / 2;
if (inverted)
{
g2.clipRect(0, 0, slider.getHeight(), thumbPos);
}
else
{
g2.clipRect(0, thumbPos, slider.getWidth(), slider.getHeight() - thumbPos);
}
}
g2.setColor(trackColor);
g2.fill(trackShape);
g2.setClip(clip);
}
#Override
public void paintThumb(final Graphics g)
{
g.setColor(thumbColor);
g.fillOval(thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height);
}
#Override
public void paintFocus(final Graphics g) {}
}
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 would like the cell of my JTable to be aligned horizontally with the selected panels.Here is the a SSCCE to illustrate my problem. Thanks for any help.
public class TableCellAlignment {
private final static int MAX = 50;
private static SelectablePanel[] selectablePanels = new SelectablePanel[MAX];
private static JScrollPane slaveScrollPane = new JScrollPane();
private static JScrollPane masterScrollPane = new JScrollPane();
private static JTable slaveTable = new JTable();
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new TableCellAlignment().createGUI();
}
});
}
private static void createGUI() {
JFrame f = new JFrame("TableCellAlignment");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel masterPanel = new JPanel(new GridLayout(MAX, 1));
Integer[][] objs = new Integer[MAX][1];
for (int i = 0; i < MAX; i++) {
objs[i][0] = new Integer(i);
SelectablePanel masterSelectablePanel = new SelectablePanel();
masterSelectablePanel.setNum(i);
selectablePanels[i] = masterSelectablePanel;
masterPanel.add(masterSelectablePanel);
}
DefaultTableModel model = new DefaultTableModel(objs, new Object[]{"Column1"});
model.addTableModelListener(new TableModelListener() {
#Override
public void tableChanged(TableModelEvent e) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
slaveTable.setRowHeight(20);
}
});
}
});
model.addRow(objs);
slaveTable.setModel(model);
final JPanel p = new JPanel(new GridLayout(1, 2));
masterScrollPane.setViewportView(masterPanel);
slaveScrollPane.setViewportView(slaveTable);
p.add(masterScrollPane);
p.add(slaveScrollPane);
f.add(p);
f.setSize(400, 200);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static class SelectablePanel extends JPanel {
private PropertyChangeSupport cs;
private int num;
private boolean selected = false;
public SelectablePanel() {
cs = new PropertyChangeSupport(this);
cs.addPropertyChangeListener(new SelectedPropertyChangeListener());
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
setSelected(true);
}
});
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public boolean isSelected() {
return selected;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (selected) {
Color c = g.getColor();
g.setColor(Color.blue);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.white);
FontMetrics fm = g.getFontMetrics();
g.drawString("" + getNum(), getWidth() / 2, (getHeight() + (fm.getAscent() - fm.getDescent())) / 2);
g.setColor(c);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 20);
}
public void setSelected(boolean selected) {
boolean oldVal = isSelected();
this.selected = selected;
cs.firePropertyChange("selected", oldVal, selected);
repaint();
}
private class SelectedPropertyChangeListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("selected")) {
boolean selected = (boolean) evt.getNewValue();
if (selected) {
for (int i = 0; i < MAX; i++) {
SelectablePanel masterSelectablePanel = selectablePanels[i];
if (i != getNum() && masterSelectablePanel.isSelected()) {
masterSelectablePanel.setSelected(false);
}
}
slaveTable.setRowSelectionInterval(getNum(), getNum());
final JViewport viewport = slaveScrollPane.getViewport();
Rectangle rect = new Rectangle(getBounds().x, getBounds().y, 1, 1);
Rectangle r2 = viewport.getVisibleRect();
slaveTable.scrollRectToVisible(new Rectangle(rect.x, rect.y, (int)r2.getWidth(), (int)r2.getHeight()));
}
}
}
}
}
}
viewport.setViewPosition( pt ); as shown here.
It's basic math and it does not require access to the viewport:
// in the isSelected block of the propertyChangeListener:
JComponent current = (JComponent) evt.getSource();
slaveTable.setRowSelectionInterval(getNum(), getNum());
// get the cellRect of the selected cell
Rectangle cellRect = slaveTable.getCellRect(getNum(), 0, false);
// get the bounds of the selected panel
Rectangle panelRect = current.getBounds();
// get the visible rect of the selected panel's parent
Rectangle parentVisibleRect = ((JComponent) current.getParent()).getVisibleRect();
// the diff above the current (to the parent's visible rect)
int aboveCurrent = panelRect.y - parentVisibleRect.y;
// translate the cell rect
cellRect.y = Math.max(cellRect.y - aboveCurrent, 0);
// adjust size to slaveTable's visible height
cellRect.height = slaveTable.getVisibleRect().height;
slaveTable.scrollRectToVisible(cellRect);
Note that this snippet assumes that the view's viewport of both the panel's parent and the table have the same size, so either remove the header from the table, or add a header to the panel's scrollPane, or use a LayoutManager which can align the viewports of the two scrollPanes.
I'm trying to have Aero Glass look in my JPanel. Is it possible do such a thing?
How to add Aero effect to JFrame - like this picture?
please read tutorials How to Create Translucent, How to Create Translucent and Shaped Windows, then by using javax.swing.Timer is possible (for example)
import java.awt.event.*;
import java.awt.Color;
import java.awt.AlphaComposite;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
public class ButtonTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ButtonTest().createAndShowGUI();
}
});
}
private JFrame frame;
private JButton opaqueButton1;
private JButton opaqueButton2;
private SoftJButton softButton1;
private SoftJButton softButton2;
public void createAndShowGUI() {
opaqueButton1 = new JButton("Opaque Button");
opaqueButton2 = new JButton("Opaque Button");
softButton1 = new SoftJButton("Transparent Button");
softButton2 = new SoftJButton("Transparent Button");
opaqueButton1.setBackground(Color.GREEN);
softButton1.setBackground(Color.GREEN);
frame = new JFrame();
frame.getContentPane().setLayout(new java.awt.GridLayout(2, 2, 10, 10));
frame.add(opaqueButton1);
frame.add(softButton1);
frame.add(opaqueButton2);
frame.add(softButton2);
frame.setSize(567, 350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Timer alphaChanger = new Timer(30, new ActionListener() {
private float incrementer = -.03f;
#Override
public void actionPerformed(ActionEvent e) {
float newAlpha = softButton1.getAlpha() + incrementer;
if (newAlpha < 0) {
newAlpha = 0;
incrementer = -incrementer;
} else if (newAlpha > 1f) {
newAlpha = 1f;
incrementer = -incrementer;
}
softButton1.setAlpha(newAlpha);
softButton2.setAlpha(newAlpha);
}
});
alphaChanger.start();
Timer uiChanger = new Timer(3500, new ActionListener() {
private LookAndFeelInfo[] laf = UIManager.getInstalledLookAndFeels();
private int index = 1;
#Override
public void actionPerformed(ActionEvent e) {
try {
UIManager.setLookAndFeel(laf[index].getClassName());
SwingUtilities.updateComponentTreeUI(frame);
} catch (Exception exc) {
exc.printStackTrace();
}
index = (index + 1) % laf.length;
}
});
uiChanger.start();
}
public static class SoftJButton extends JButton {
private static final JButton lafDeterminer = new JButton();
private static final long serialVersionUID = 1L;
private boolean rectangularLAF;
private float alpha = 1f;
public SoftJButton() {
this(null, null);
}
public SoftJButton(String text) {
this(text, null);
}
public SoftJButton(String text, Icon icon) {
super(text, icon);
setOpaque(false);
setFocusPainted(false);
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
repaint();
}
#Override
public void paintComponent(java.awt.Graphics g) {
java.awt.Graphics2D g2 = (java.awt.Graphics2D) g;
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
if (rectangularLAF && isBackgroundSet()) {
Color c = getBackground();
g2.setColor(c);
g.fillRect(0, 0, getWidth(), getHeight());
}
super.paintComponent(g2);
}
#Override
public void updateUI() {
super.updateUI();
lafDeterminer.updateUI();
rectangularLAF = lafDeterminer.isOpaque();
}
}
}
Maybe this blog post will help you more. The author describes an approach where he rebuilds the whole Windows Aero effect. Here is his working example:
(source: centigrade.de)
So I have a JSplitPane, and two JPanels - one on top, one on the bottom. In both panels I overrode the paintComponent method and added my own graphics. In the bottom panel, I wanted to add an animation. When the panel does not repaint, it's fine, but as soon as the Timer (javax.swing.Timer) starts to call repaints, the bottom panel mimics the appearance of the top panel and glitches out. The actual animations are not refreshed, but rather it keeps on adding (like a dragged paintbrush instead of a moving object).
Here's the code for the Bottom Panel class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
import javax.swing.Timer;
public class WaitControls extends JPanel {
private int pos;
public WaitControls(){
setBackground(Color.gray);
pos = 0;
}
public void progress(){
//animation timer:
Timer timer = new Timer(30, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
pos++;
repaint();
}
});
timer.start();
}
#Override
public void paintComponent(Graphics g){
g.fillRect(pos, pos, 10, 20);
}
}
And here's the code for the Splitpane class:
//my classes (imported packages)
import rcc.controls.ControlPanel;
import rcc.controls.InitControls;
import rcc.controls.WaitControls;
import rcc.video.Screen;
import javax.swing.JSplitPane;
public class MainPanel extends JSplitPane{
public RCC rcc;
public Screen screen;
private int height;
public ControlPanel curPanel;
public MainPanel(RCC rcc, Screen screen, int height){
super(JSplitPane.VERTICAL_SPLIT);
this.rcc = rcc;
this.screen = screen;
this.height = height;
setDividerSize(2);
setEnabled(false);
setTopComponent(screen);
setToInitControls();
}
//sets the control panel to init controls ***WORKS FINE***
public void setToInitControls(){
InitControls initCtrls = new InitControls(this);
setBottomComponent(initCtrls);
curPanel = initCtrls;
setDividerLocation(height / 4 * 3);
}
//sets the control panel to wait controls (trying to connect) ***GLITCHES***
public void setToWaitControls(){
WaitControls waitCtrls = new WaitControls();
setBottomComponent(waitCtrls);
curPanel = waitCtrls;
setDividerLocation(height / 4 * 3);
waitCtrls.progress();
}
}
The top panel is a bit complicated. It involves mouse action (including a MouseEntered listener) and animates to interact with user mouse input.
The strange thing is, I have another bottom panel that was swapped out that also uses animations, and a timer, and does not have this glitch.
Any ideas what may have caused this? Thank you for all your help!
I can't imagine how your animations works,
1/ but if animation(s) depends of by any of Listener then Timer must be Timer#restart();
2/ check (example), how to pass addNotify()/removeNotify() for start/stop animatiom(s)
NOTE required fullHD monitor for better output or change code line
for (int iPanels = 0; iPanels < 3; iPanels++) {
to
for (int iPanels = 0; iPanels < 2; iPanels++) {
Example:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class AnimationBackground {
public AnimationBackground() {
Random random = new Random();
JFrame frame = new JFrame("Animation Background");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLayout(new GridLayout(0, 3, 10, 10));
for (int iPanels = 0; iPanels < 3; iPanels++) {
final MyJPanel panel = new MyJPanel();
panel.setBackground(Color.BLACK);
for (int i = 0; i < 50; i++) {
Star star = new Star(new Point(random.nextInt(490), random.nextInt(490)));
star.setColor(new Color(100 + random.nextInt(155), 100 + random.nextInt(155), 100 + random.nextInt(155)));
star.setxIncr(-3 + random.nextInt(7));
star.setyIncr(-3 + random.nextInt(7));
panel.add(star);
}
panel.setLayout(new GridLayout(10, 1));
JLabel label = new JLabel("This is a Starry background.", JLabel.CENTER);
label.setForeground(Color.WHITE);
panel.add(label);
JPanel stopPanel = new JPanel();
stopPanel.setOpaque(false);
stopPanel.add(new JButton(new AbstractAction("Stop this madness!!") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
panel.stopAnimation();
}
}));
panel.add(stopPanel);
JPanel startPanel = new JPanel();
startPanel.setOpaque(false);
startPanel.add(new JButton(new AbstractAction("Start moving...") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
panel.startAnimation();
}
}));
panel.add(startPanel);
frame.add(panel);
}
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
AnimationBackground animationBackground = new AnimationBackground();
}
});
}
class Star extends Polygon {
private static final long serialVersionUID = 1L;
private Point location = null;
private Color color = Color.YELLOW;
private int xIncr, yIncr;
static final int WIDTH = 500, HEIGHT = 500;
Star(Point location) {
int x = location.x;
int y = location.y;
this.location = location;
this.addPoint(x, y + 8);
this.addPoint(x + 8, y + 8);
this.addPoint(x + 11, y);
this.addPoint(x + 14, y + 8);
this.addPoint(x + 22, y + 8);
this.addPoint(x + 17, y + 12);
this.addPoint(x + 21, y + 20);
this.addPoint(x + 11, y + 14);
this.addPoint(x + 3, y + 20);
this.addPoint(x + 6, y + 12);
}
public void setColor(Color color) {
this.color = color;
}
public void move() {
if (location.x < 0 || location.x > WIDTH) {
xIncr = -xIncr;
}
if (location.y < 0 || location.y > WIDTH) {
yIncr = -yIncr;
}
translate(xIncr, yIncr);
location.setLocation(location.x + xIncr, location.y + yIncr);
}
public void setxIncr(int xIncr) {
this.xIncr = xIncr;
}
public void setyIncr(int yIncr) {
this.yIncr = yIncr;
}
public Color getColor() {
return color;
}
}
class MyJPanel extends JPanel {
private static final long serialVersionUID = 1L;
private ArrayList<Star> stars = new ArrayList<Star>();
private Timer timer = new Timer(20, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Star star : stars) {
star.move();
}
repaint();
}
});
public void stopAnimation() {
if (timer.isRunning()) {
timer.stop();
}
}
public void startAnimation() {
if (!timer.isRunning()) {
timer.start();
}
}
#Override
public void addNotify() {
super.addNotify();
timer.start();
}
#Override
public void removeNotify() {
super.removeNotify();
timer.stop();
}
MyJPanel() {
this.setPreferredSize(new Dimension(520, 520));
}
public void add(Star star) {
stars.add(star);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (Star star : stars) {
g.setColor(star.getColor());
g.fillPolygon(star);
}
}
}
}