one of my menus is simply an image, and a button to go 'back.'
The problem is, the back button always loads before the image, even though it is after in the code.
Is there any way to fix this? I'm brand new to programming, so the best way I could think of would be to pause the method somehow, say for 3 seconds, while the picture loads, THEN load the back button.
I have tried using thread.sleep(3000) but if I do that, the image doesn't load at all! Maybe I am using it wrong?
public void render(Graphics g){
if(Instscrn==true){
g.drawImage(InstructionScreen, 0, 0, Resources.sp);
if(instclose){
g.setFont(new Font("Arial", Font.PLAIN, 30));
g.setColor(Color.BLACK);
g.drawString("Back", 672, 552);
}
With thread.sleep
public void render(Graphics g){
if(Instscrn==true){
g.drawImage(InstructionScreen, 0, 0, Resources.sp);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(instclose){
g.setFont(new Font("Arial", Font.PLAIN, 30));
g.setColor(Color.BLACK);
g.drawString("Back", 672, 552);
}
Thanks for your help!
You can load image on render(Graphics g) without pausing any method:
boolean inited = false;
Image i;
public void render(Graphics g){
if(!inited) {
//here, init your image, for example: download files from web or load resources
try {
i = ImageIO.read(new File(""));//loading image
} catch (IOException e) {
e.printStackTrace();//error
}
inited=true;
}
g.drawImage...
}
You can't pause a method, but you can pause a thread (with method):
public static void main(String[] args) throws InterruptedException {
final Thread pauseable = new Thread("Pauseable method/thread") {
//Pauseable method
public void run() {
for(int i=0; i<20; i++) {
System.out.println("Working");
sleepMethod();
}
}
//Sleep for 1 seconds
public void sleepMethod() {
try {
sleep(1000);
} catch(Throwable t){}
}
};
pauseable.start();
JFrame f = new JFrame();
JButton pause = new JButton("Pause");
JButton start = new JButton("Resume");
pause.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
try {
pauseable.suspend();
} catch(Throwable t) {
t.printStackTrace();
}
}});
start.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
try {
pauseable.resume();
} catch(Throwable t) {
t.printStackTrace();
}
}});
//STYLE OF BUTTONS ETC.:
JPanel p = new JPanel(new GridLayout(1,2));
p.add(pause);
p.add(start);
f.getContentPane().add(p);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
pauseable.join(); //If you want wait to end of running method
System.out.println("Method pauseable.run() was ended!");
}
Related
It hasn't been long since I started developing Java.
This code was run by Eclipse. When I run this code javaSE-1.8, only mimage appears, and when I remove and run 'paintComponenets(g);',quit button and start button appear, and mimage disappears. I think 'paintComponents' is the problem. How do I solve this problem
public class Mainscreen extends JFrame {
private Image screenImage;
private Graphics screenGraphics;
private Image mImage = new
ImageIcon(Main.class.getResource("../img/unnamed.jpg")).getImage();
private ImageIcon quitEnter = new
ImageIcon(Main.class.getResource("../img/startButtonBasic1.jpg"));
private ImageIcon quitBasic = new
ImageIcon(Main.class.getResource("../img/startButtonEntered1.jpg"));
private ImageIcon startEnter = new
ImageIcon(Main.class.getResource("../img/startButtonBasic.jpg"));
private ImageIcon startBasic = new
ImageIcon(Main.class.getResource("../img/startButtonEntered.jpg"));
private JButton quitButton = new JButton(quitBasic);
private JButton startButton = new JButton(startBasic);
public Mainscreen() {
setTitle("Main");
setSize(900, 900);
setResizable(false);
setLocationRelativeTo(null);
setLayout(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
startButton.setBounds(40 ,200, 400, 100);
startButton.setBorderPainted(false);
startButton.setContentAreaFilled(false);
startButton.setFocusPainted(false);
startButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
startButton.setIcon(startEnter);
startButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
public void mouseExited(MouseEvent e) {
startButton.setIcon(startBasic);
startButton.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
public void MousePressed(MouseEvent e) {
//select
}
});
add(startButton);
quitButton.setBounds(40, 500, 400, 100);
quitButton.setBorderPainted(false);
quitButton.setContentAreaFilled(false);
quitButton.setFocusPainted(false);
quitButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
quitButton.setIcon(quitEnter);
quitButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
public void mouseExited(MouseEvent e) {
quitButton.setIcon(quitBasic);
quitButton.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
public void MousePressed(MouseEvent e) {
try {
Thread.sleep(1000);
}
catch(InterruptedException ex){
ex.printStackTrace();
}
System.exit(0);
}
});
add(quitButton);
}
public void paint(Graphics g) {
screenImage = createImage(Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT);
screenGraphics = screenImage.getGraphics();
screenDraw(screenGraphics);
g.drawImage(screenImage, 0, 0, null);
}
public void screenDraw(Graphics g) {
g.drawImage(mImage, 0, 0, null);
paintComponents(g);
this.repaint();
}
}
I'm new to Stackoverflow and tried to follow the rules as much as possible. I haven't been able to solve this problem for hours. When I start the program it seldom starts strangely:
properly started: correct image:
not properly started: white screen:
If you see an error in the code and help me fix it I would appreciate it. any correction
public class MainClass extends JPanel implements Runnable, MouseListener {
enum MenuState {
xMenu1, xMenu2;
}
private MenuState menuState = MenuState.xMenu1;
JFrame frame;
private Image bgImage, playButtonImage, backButtonImage;
private Rectangle playButton, backButton;
public MainClass() {
frame = new JFrame("TEST");
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setUndecorated(true);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBackground(Color.BLACK);
frame.setFocusable(true);
frame.addMouseListener(this);
frame.add(this);
try {
bgImage = ImageIO.read(getClass().getResourceAsStream("/Data/background.png"));
playButtonImage = ImageIO.read(getClass().getResource("/Data/playButton2.png"));
backButtonImage = ImageIO.read(getClass().getResource("/Data/backButton.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
playButton = new Rectangle(900, 400, 214, 78);
backButton = new Rectangle(5, 5, 136, 92);
Thread thread = new Thread(this);
thread.start();
System.out.println("thread started");
}
public static void main(String[] args) {
new MainClass();
}
#Override
public void run() {
while (true) {
System.out.println("run method started");
if (menuState == menuState.xMenu1) {
} else if (menuState == menuState.xMenu2) {
}
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void paint(Graphics g) {
if (menuState == menuState.xMenu1) {
g.drawImage(playButtonImage, playButton.x, playButton.y, this); // THIS IS THE 77th LINE
} else if (menuState == menuState.xMenu2) {
g.drawImage(bgImage, 0, 0, this);
g.drawImage(backButtonImage, backButton.x, backButton.y, this);
}
}
#Override
public void mousePressed(MouseEvent e) {
if (menuState == menuState.xMenu1) {
if (playButton.intersects(e.getX(), e.getY(), 1, 1)) {
menuState = menuState.xMenu2;
}
} else if (menuState == menuState.xMenu2) {
if (backButton.intersects(e.getX(), e.getY(), 1, 1)) {
menuState = menuState.xMenu1;
}
}
}
}
I'm trying to synchronize this code: what I want is that the class Gioca waits until the class Gioco calls the method fine (fine should stop the thread) but as the Gioca class invokes the run method it prints on the console the string "Fine" even thow the class Gioco hasn't called the method fine() yet.
public class Gioca implements Runnable
{
private int vite;
private int recuperi;
public Gioca()
{
vite=3;
recuperi=0;
}
public void gioca()
{
Thread t=new Thread(new Gioco(vite));
try
{
t.start();
t.join();
}
catch (Exception ex) {}
System.out.println("Fine");
}
#Override
public void run()
{
gioca();
}
}
public class Gioco extends Canvas implements ActionListener, KeyListener, Runnable
{
private int direzione;
private Timer timer;
private JFrame f;
private int vite;
private int velocità;
private int spazio;
private Personaggio p;
private int pos;
private LinkedList<Ostacolo> o;
private Random r;
private int po;
private Image imm1=new ImageIcon(this.getClass().getResource("images/sfondo.jpg")).getImage();
private Image imm2=new ImageIcon(this.getClass().getResource("images/cuore.png")).getImage();
public Gioco(int vite)
{
r=new Random();
try
{
File file=new File("images/punteggio.txt");
Scanner scanner=new Scanner(file);
spazio=scanner.nextInt();
}
catch (Exception e) {}
direzione=3;
this.vite=vite;
o=new LinkedList();
for(int i=0; i<20; i++)
o.add(new Ostacolo(Math.abs(400*i)+1000));
p=new Personaggio();
this.velocità=2;
timer=new Timer(10, this);
f=new JFrame("Gioco");
f.setSize(1000, 700);
f.setResizable(false);
f.setLocation(200,200);
f.add(this);
f.addKeyListener(this);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent ae)
{
if(direzione==2)
{
velocità-=2;
if(velocità<2)
velocità=2;
}
if(direzione==1)
p.setY(5);
if(direzione==0)
p.setY(-5);
spazio+=velocità;
if(spazio%1000<10)
velocità++;
pos=(pos+velocità)%4500;
po=-pos;
for(int i=0; i<20; i++)
{
o.get(i).muovi(velocità);
if(o.get(i).getX()<-100)
{
o.remove(i);
o.add(new Ostacolo(i*400));
}
}
verificaCollisioni();
repaint();
}
public void verificaCollisioni()
{
for(int i=0; i<20; i++)
{
if(o.get(i).getX()>300 && o.get(i).getX()<350)
{
int r[]=o.get(i).getDimensioni();
if(r[0]<p.getY() && r[1]>p.getY())
{
}
else
fine();
}
}
}
private void fine()
{
try
{
Thread.sleep(3000);
}
catch(Exception e){}
timer.stop();
try
{
File file=new File("images/punteggio.txt");
file.createNewFile();
FileOutputStream f=new FileOutputStream(file);
f.flush();
String sPunteggio=String.valueOf(spazio);
byte[] scrivi=sPunteggio.getBytes();
f.write(scrivi);
}
catch(Exception e){}
f.dispose();
}
#Override
public void keyPressed(KeyEvent ke)
{
int c=ke.getKeyCode();
if(c == 40)
direzione=1;
if(c == 38)
direzione=0;
if(c==32)
direzione=2;
}
public void paint(Graphics g)
{
Image workspace=createImage(getWidth(),getHeight());
Graphics2D buffer=(Graphics2D) workspace.getGraphics();
buffer.drawImage(imm1, po, 0, this);
buffer.setColor(new Color(242, 54, 33));
buffer.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));
buffer.drawString(""+(spazio/100), 10, 20);
buffer.drawImage(imm2, 940, 4, this);
buffer.setColor(new Color(13, 226, 13));
buffer.drawString(""+vite, 920, 20);
buffer.drawImage(p.getImage(), 300, p.getY(), this);
for(int i=0; i<20; i++)
{
Ostacolo tmp=o.get(i);
buffer.drawImage(tmp.getImage(), tmp.getX(),tmp.getY(), this);
}
Graphics2D g2=(Graphics2D)g;
g2.drawImage(workspace, 0, 0, this);
buffer.dispose();
}
public void update(Graphics g)
{
paint(g);
}
public void keyReleased(KeyEvent ke) {direzione=3;}
public void keyTyped(KeyEvent ke) {}
#Override
public void run()
{
f.setVisible(true);
timer.start();
}
}
This code, using the same instructions, works well
public class Campana implements Runnable{
private String suono;
private int volte;
public Campana(String suono,int volte)
{
this.suono =suono;
this.volte=volte;
}
public void run()
{
for(int i=0;i<volte;i++) {
System.out.println((i+1)+" "+suono);
}
}
}
public class Suona {
public static void main(String args[]){
Thread campana1=new Thread(new Campana("din", 5));
Thread campana2=new Thread(new Campana("don", 5));
Thread campana3=new Thread(new Campana("dan", 5));
try {
campana1.start();
campana1.join();
campana2.start();
campana2.join();
campana3.start();
campana3.join();
} catch (InterruptedException ex) {
Logger.getLogger(Suona.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
t.join(); in this case waits for run in Giocoto terminate. That method terminates after
f.setVisible(true);
timer.start();
have completed, which will be very fast since Timer will run actionPerformed a different thread from the one that timer.start(); is called in. It does not wait until the timer has been stopped. You can fix this by introducing some form of synchronization in your run method. I would not recommend a while loop since that will waste resources on running the loop. Instead consider using a CountDownLatch (javadoc link):
Add this to Gioco:
private final CountDownLatch doneSignal = new CountDownLatch(1);
At the end of fine() call doneSignal.countDown(). And finally change your run() method in Gioco to something like this:
#Override
public void run()
{
f.setVisible(true);
timer.start();
try {
doneSignal.await();
} catch (InterruptedException ex) {}//Logg this or something. Shouldn't really ever happen.
}
I'm trying to capture the screen without including my application's window. To do this I first call setVisible(false), then I call the createScreenCapture method, and finally I call setVisible(true). This isn't working however and I'm still getting my applications window in the screen capture. If I add a call to sleep this seems to resolve the issue, but I know this is bad practice. What is the right way to do this?
Code:
setVisible(false);
BufferedImage screen = robot.createScreenCapture(rectScreenSize);
setVisible(true);
Have you tried to use SwingUtilities.invokeLater() and run the capture inside of the runnable passed as an argument? My guess is that the repaint performed to remove your application is performed right after the end of the current event in the AWT-EventQueue and thus invoking the call immediately still captures your window. Invoking the createCapture in a delayed event through invokeLater should fix this.
you have to delay this action by implements Swing Timer, for example
import javax.imageio.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
public class CaptureScreen implements ActionListener {
private JFrame f = new JFrame("Screen Capture");
private JPanel pane = new JPanel();
private JButton capture = new JButton("Capture");
private JDialog d = new JDialog();
private JScrollPane scrollPane = new JScrollPane();
private JLabel l = new JLabel();
private Point location;
private Timer timer1;
public CaptureScreen() {
capture.setActionCommand("CaptureScreen");
capture.setFocusPainted(false);
capture.addActionListener(this);
capture.setPreferredSize(new Dimension(300, 50));
pane.add(capture);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(pane);
f.setLocation(100, 100);
f.pack();
f.setVisible(true);
createPicContainer();
startTimer();
}
private void createPicContainer() {
l.setPreferredSize(new Dimension(700, 500));
scrollPane = new JScrollPane(l,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setBackground(Color.white);
scrollPane.getViewport().setBackground(Color.white);
d.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
d.add(scrollPane);
d.pack();
d.setVisible(false);
d.addWindowListener(new WindowListener() {
public void windowOpened(WindowEvent e) {
}
public void windowClosing(WindowEvent e) {
f.setVisible(true);
}
public void windowClosed(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowActivated(WindowEvent e) {
}
public void windowDeactivated(WindowEvent e) {
}
});
}
private void startTimer() {
timer1 = new Timer(1000, new AbstractAction() {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
capture.doClick();
f.setVisible(false);
}
});
}
});
timer1.setDelay(500);
timer1.setRepeats(false);
timer1.start();
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("CaptureScreen")) {
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); // gets the screen size
Robot r;
BufferedImage bI;
try {
r = new Robot(); // creates robot not sure exactly how it works
Thread.sleep(1000); // waits 1 second before capture
bI = r.createScreenCapture(new Rectangle(dim)); // tells robot to capture the screen
showPic(bI);
saveImage(bI);
} catch (AWTException e1) {
e1.printStackTrace();
} catch (InterruptedException e2) {
e2.printStackTrace();
}
}
}
private void saveImage(BufferedImage bI) {
try {
ImageIO.write(bI, "JPG", new File("screenShot.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
private void showPic(BufferedImage bI) {
ImageIcon pic = new ImageIcon(bI);
l.setIcon(pic);
l.revalidate();
l.repaint();
d.setVisible(false);
//location = f.getLocationOnScreen();
//int x = location.x;
//int y = location.y;
//d.setLocation(x, y + f.getHeight());
d.setLocation(150, 150);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
d.setVisible(true);
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
CaptureScreen cs = new CaptureScreen();
}
});
}
}
When setting a busy cursor on the glass pane of the application frame after closing a modal dialog, the busy cursor is not always displayed. Sometimes it works (the first time it is mostly always working), sometimes not.
Even better, when setting the busy cursor before opening the dialog. The busy cursor get displayed but when moving the mouse inside and then outside the dialog the busy cursor is not displayed anymore.
Note that I observe the following bug on Linux only. On Mac OS X or Windows the behavior is deterministic and consistent.
Another hint, in the first case of the code sample, when the mouse is NOT entering the dialog and the YES_OPTION is selected using the keyboard, the busy mouse cursor is always shown. Also in this case, the "Please wait..." label on the glass pane get never painted.
Here a SSCCE demonstrating these bugs:
import java.awt.event.*;
import javax.swing.*;
public class TestFrame extends JFrame {
private JPanel panel;
private JPanel glassPane;
public TestFrame() {
final JButton button1 = new JButton(new AbstractAction("Start activity indicator after closing the dialog") {
#Override
public void actionPerformed(ActionEvent e) {
doAction1();
}
});
final JButton button2 = new JButton(new AbstractAction("Start activity indicator before opening the dialog") {
#Override
public void actionPerformed(ActionEvent e) {
doAction2();
}
});
panel = new JPanel();
panel.add(button1);
panel.add(button2);
getContentPane().add(panel, BorderLayout.NORTH);
glassPane = (JPanel) getGlassPane();
glassPane.setLayout(new BorderLayout());
glassPane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
glassPane.add(new JLabel("Please Wait..."), BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 600);
setVisible(true);
}
public void doAction1() {
System.out.println("IsStartingInEDT?: "+ SwingUtilities.isEventDispatchThread());
final int response = JOptionPane.showConfirmDialog(this, "Click on the YES_OPTION, busy indicator must start (if it does, try again).");
if (JOptionPane.YES_OPTION == response) {
startActivity();
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
}
stopActivity();
}
}
public void doAction2() {
startActivity();
System.out.println("IsStartingInEDT?: "+ SwingUtilities.isEventDispatchThread());
final int response = JOptionPane.showConfirmDialog(this, "Move the mouse inside the dialog (me) and then outside, the busy indicator is not shown anymore");
if (JOptionPane.YES_OPTION == response) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
}
}
stopActivity();
}
public void startActivity() {
System.out.println("TestFrame.startActivity()");
glassPane.setVisible(true);
}
public void stopActivity() {
System.out.println("TestFrame.stopActivity()");
glassPane.setVisible(false);
}
/**
* #param args
*/
public static void main(String[] args) {
new TestFrame();
}
}
At the moment I did not find any related issues in the JavaBug parade. I will search further before opening a new one.
I also already read the following article but it is not very convenient as making a good modal dialog from a non-modal one is not straightforward:
http://www.javaspecialists.eu/archive/Issue065.html
Can anyone provide some help?
Thanks in advance, Pierre
You have some threading issue here.
Is IsStartingInEDT true?
If yes, you are doing it wrong because:
You should not sleep in UI thread. This would stop the screen update.
If no, you are doing it wrong because:
OptionPane.showConfirmDialog() must be called from the UI thread.
you should do something like this:
public void doAction1() {
if (!SwingUtilities.isEventDispatchThread()) {
System.err.println("error, must be edt");
return;
}
final int response = JOptionPane.showConfirmDialog(this, "Click on the YES_OPTION, busy indicator must start (if it does, try again).");
if (JOptionPane.YES_OPTION == response) {
startActivity(); // change glass panel in edt
// new thread for long standing task
new Thread( new Runnable() { public void run() {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
}
SwingUtilities.invokeAndWait(new Runnable(){ public void run() {
// changing glass panel need edt
stopActivity();
});
}).start();
}
}
1st. by using Tread.sleep(int) pretty sure to block EDT, with all issues desribed about Concurrency in Swing
2.nd works because initializations for JOptionPane create a new EDT
here is simple demonstrations about ...., please that only example and be sure that is against all Swing rules, but demostrated lock and unlock EDT by usage Tread.sleep(int) during EDT
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class ShakeComponents1 {
private JFrame frame = new JFrame();
private final String items[] = {"One", "Two", "Three"};
private Timer timer;
private JPanel panel = new JPanel();
private JPanel buttonPanel = new JPanel();
private JButton button = new JButton(" Exit ");
private boolean repeats = true;
private boolean runs = false;
private Color clr[] = {Color.red, Color.blue, Color.magenta};
private Insets initMargin;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ShakeComponents1().makeUI();
}
});
}
public void makeUI() {
buttonPanel = new JPanel();
buttonPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
buttonPanel.setLayout(new BorderLayout());
button.setPreferredSize(new Dimension(100, 45));
button.setForeground(Color.darkGray);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
Runnable doRun = new Runnable() {
#Override
public void run() {
System.exit(0);
}
};
SwingUtilities.invokeLater(doRun);
}
});
button.addMouseListener(new java.awt.event.MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
if (runs) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
runs = false;
timer.stop();
changePnlBorder(new EmptyBorder(5, 5, 5, 5));
changeBtnForegroung(Color.darkGray);
}
});
}
}
#Override
public void mouseExited(MouseEvent e) {
if (!runs) {
timer.start();
runs = true;
}
}
});
buttonPanel.add(button);
final Insets margin = button.getMargin();
panel.add(buttonPanel);
for (int i = 0; i < 2; i++) {
JComboBox combo = new JComboBox(items);
combo.setMinimumSize(new Dimension(50, 25));
combo.setMaximumSize(new Dimension(150, 25));
combo.setPreferredSize(new Dimension(100, 25));
combo.addActionListener(new ShakeAction());
panel.add(combo);
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setLocation(50, 50);
frame.setVisible(true);
timer = new Timer(500, new ShakeAction());
timer.setRepeats(repeats);
initMargin = button.getMargin();
}
private class ShakeAction extends AbstractAction {
private static final long serialVersionUID = 1L;
private int noColor = 0;
private Border border;
private int count = 0;
#Override
public void actionPerformed(ActionEvent e) {
timer.start();
if (count > 5) {
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
changeBtnForegroung(Color.darkGray);
Thread.sleep(500);
count = 0;
Thread.sleep(750);
} catch (Exception e) {
System.out.println(e);
}
}
}).start();
} else {
new Thread(new Runnable() {
#Override
public void run() {
try {
runs = true;
if (noColor < 2) {
noColor++;
changeBtnForegroung(clr[noColor]);
} else {
noColor = 0;
changeBtnForegroung(clr[noColor]);
}
changeBtnMargin(new Insets(initMargin.top, initMargin.left + 10, initMargin.bottom, initMargin.right - 10));
border = new EmptyBorder(0, 5, 10, 5);
changePnlBorder(border);
Thread.sleep(100);
changeBtnMargin(new Insets(initMargin.top, initMargin.left - 10, initMargin.bottom, initMargin.right + 10));
border = new EmptyBorder(0, 0, 10, 10);
changePnlBorder(border);
Thread.sleep(100);
changeBtnMargin(new Insets(initMargin.top, initMargin.left + 10, initMargin.bottom, initMargin.right - 10));
border = new EmptyBorder(5, 10, 5, 0);
changePnlBorder(border);
Thread.sleep(100);
changeBtnMargin(new Insets(initMargin.top, initMargin.left - 10, initMargin.bottom, initMargin.right + 10));
border = new EmptyBorder(10, 10, 0, 0);
changePnlBorder(border);
Thread.sleep(100);
changeBtnMargin(new Insets(initMargin.top, initMargin.left, initMargin.bottom, initMargin.right));
border = new EmptyBorder(5, 5, 5, 5);
changePnlBorder(border);
Thread.sleep(100);
count++;
} catch (Exception e) {
System.out.println(e);
}
}
}).start();
}
}
}
private void changePnlBorder(final Border b) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
buttonPanel.setBorder(b);
buttonPanel.revalidate();
buttonPanel.repaint();
}
});
}
private void changeBtnForegroung(final Color c) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
button.setForeground(c);
}
});
}
private void changeBtnMargin(final Insets margin) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
button.setMargin(margin);
}
});
}
}
conclusion -> you can create new Thread as BackGroung Task(s) wrapped into Runnable, if you wnat to simulate LongRunning Task and with Thread.sleep(int), maybe answer to your question is here
sure correct way would be by using SwingWorker for that, with Thread.sleep(int) too