I used 'Thread' and 'TimeUnit' but not know how to use in the following program. I want when WIN+E execute then after some delay of 1 or 2 second next statement run. As, next statement is in for loop so it should run after 2 seconds infinite time (because of infinite for loop). You can see ActionListener line only.
package v;
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class V extends JPanel{
private JButton V;
public V() throws AWTException{
Robot r = new Robot();
setBackground(Color.yellow);
setPreferredSize(new Dimension(800,500));
V = new JButton("PUSH");
add(V);
V.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {
for (int i=0; i>0; i++) {r.keyPress(KeyEvent.VK_WINDOWS); r.keyPress(KeyEvent.VK_E); r.keyRelease(KeyEvent.VK_WINDOWS); r.keyRelease(KeyEvent.VK_E);}
}
});
}
public static void main(String[] args) throws AWTException {
V panel = new V();
JFrame frame = new JFrame ("V");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
i would go for something like this:
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class V extends JPanel{
private JButton V;
private boolean notstarted=true;
public V() throws AWTException{
Robot r = new Robot();
setBackground(Color.yellow);
setPreferredSize(new Dimension(800,500));
V = new JButton("PUSH");
add(V);
V.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {
if(notstarted){
notstarted=false;
new Thread(new Runnable() {
#Override
public void run() {
while (true) {r.keyPress(KeyEvent.VK_WINDOWS);
r.keyPress(KeyEvent.VK_E);
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(StreamServer.class.getName()).log(Level.SEVERE, null, ex);
}
r.keyRelease(KeyEvent.VK_WINDOWS);
r.keyRelease(KeyEvent.VK_E);}
}
}).start();
}
}
});
}
public static void main(String[] args) throws AWTException {
V panel = new V();
JFrame frame = new JFrame ("V");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
As you can see i have added a boolean notstarted to control if the function have been accessed previously, so, this way you cant run that more than one and finally i have added a Thread to mitigate the impact the ActionListener could have on the thread that call it.
Anyway there should be beeter ways to achieve what you are looking for.
You can use javafx.animation.PauseTransition
PauseTransition happen = new PauseTransition(Duration.seconds(2));
happen.setOnFinished(e -> {
System.out.println("hello");
happen.playFromStart();
});
happen.play();
Like that. It will print hello every 2 seconds. That however requires you to extend javafx.application.Application and I see that you don't use javafx in your program.
You can use Thread.sleep as the other answer suggests - to sleep each 2000 miliseconds (in your loop).
There is also java.util.Timer and java.util.TimerTask. It allows you to do code every milisecond given in time. There is an excellent video of that here https://www.youtube.com/watch?v=36jbBSQd3eU
Related
I am trying to make a button that says hello world but it dose not work I tried multiple times but nothing i did made a difference
[![package com.company;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main implements ActionListener {
JButton b;
JFrame f;
public Main()
{
b=new JButton("hello");
b.addActionListener(this);
b.setBounds(100,100,95,30);
f.setTitle("first");
f.setSize(500,300);
f.add(b);
f.setVisible(true);
f.setLayout(null);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource()==b)
{
System.out.print("hello world");
}
}
public static void main(String\[\] args) {
// write your code here
new Main();
}
}][1]][1]
and this is he result it displays
You need to instantiate your JFrame in the constructor with f = new JFrame();.
JLabel two = new JLabel();
ImageIcon jaina= new ImageIcon("images/jaina.gif");
two.setBounds(0,0,300,300);
two.setIcon(jaina);
then i added the Label to my panel, it plays only once
If your gif is not set to loop, the correct solution is to modify the gif to have it loop.
Out of curiosity I mocked up this example. What if I want to animate a gif independent of its animation settings.
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.FileImageInputStream;
import java.util.List;
import java.util.ArrayList;
import java.io.File;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.EventQueue;
public class GifLabel{
public static void startGui( List<ImageIcon> imgs){
JFrame frame = new JFrame("animated gif");
JLabel label = new JLabel( );
frame.add(label);
label.setIcon(imgs.get(0));
Timer t = new Timer( 30, new ActionListener(){
int i = 0;
#Override
public void actionPerformed( ActionEvent evt ){
label.setIcon ( imgs.get(i) );
i = (i+1)%imgs.size();
}
});
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
t.start();
}
public static void main(String[] args) throws Exception{
ImageReader reader = ImageIO.getImageReadersBySuffix("GIF").next();
reader.setInput( new FileImageInputStream( new File("images/jaina.gif")));
int n = reader.getNumImages( true );
List<ImageIcon> imgs = new ArrayList<>();
for(int i = 0; i<n; i++){
imgs.add( new ImageIcon(reader.read(i)) );
}
EventQueue.invokeLater( ()->{
startGui(imgs);
});
}
}
This is way more fragile than just making sure the GIF is the correct format. Also way more code, considering the original new ImageIcon("..."); handles everything.
How can I modify the window menu of a JFrame in Java ? That's the one (in Windows) at the top left, behind the application icon, that has items such as 'Restore', 'Move', 'Minimize', 'Resize'...
Unfortunately I've only found a way to do this with the "metal decoration" (with that I mean doing JFrame.setDefaultLookAndFeelDecorated(true);). I will of course update the answer if I find one with the system LaF, but I think this is still worth an answer.
Output:
Code:
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.io.BufferedReader;
import java.io.UnsupportedEncodingException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class Example {
public Example() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame();
JMenu systemMenu = getSystemMenu(frame);
systemMenu.add(new JMenuItem("New JMenuItem"), 0);
for (Component component : systemMenu.getPopupMenu().getComponents()) {
if (component.toString().contains("JMenu")) {
((JMenuItem) component).setForeground(Color.RED);
}
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JMenu getSystemMenu(JFrame frame) {
for (Component c1 : frame.getLayeredPane().getComponents()) {
if (c1.toString().contains("MetalTitlePane")) {
for (Component c2 : ((Container) c1).getComponents()) {
if (c2.toString().contains("SystemMenuBar")) {
return (JMenu) ((Container) c2).getComponent(0);
}
}
}
}
return null;
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Example();
}
});
}
}
I have a JFrame which contains a JPanel with the JButton "Press Me"
Pressing the "Press me" button will change to another JPanel(SecondPanel) within the same JFrame
I am facing a problem where there is a 10 second delay when i press the "Press Me" button before the SecondPanel appears.
This 10 second delay is caused the Timer event .
I wish for the SecondPanel to appear before the Timer event start.
What is happening now is that the Timer event starts , i am waiting at the "Press Me" button for 10 seconds , before the SecondPanel appears ,
can someone help me resolve this issue
Thanks
Main class used to run the project
package testing;
import java.io.*;
import java.security.*;
import javax.xml.bind.DatatypeConverter;
import java.lang.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
public class Testing extends JPanel
{
public static void main(String[] args)
{
frame = new JFrame();
LoginPanel lp = new LoginPanel();
frame.add(lp);
frame.pack();
frame.validate();
frame.setVisible(true);
}
static JFrame frame;
}
LoginPanel class
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class LoginPanel extends JPanel
{
LoginPanel()
{
Loginbtn = new JButton("Press Me");
Loginbtn.addActionListener(new LoginButtonListener());
add(Loginbtn);
}
private class LoginButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
SecondPanel sp = new SecondPanel();
Utility.ChangePanel(sp);
sp.run();
}
}
JButton Loginbtn;
}
SecondPanel class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class SecondPanel extends JPanel
{
SecondPanel()
{
setLayout(new GridLayout(2,2));
//set deck image
File deckfile = new File("./src/testing/Ace_Club_1_1.png"); //deck image file location
try
{
Deckimg = ImageIO.read(deckfile); //read deck image
}
catch (IOException e)
{
}
Image scaledInstance = Deckimg.getScaledInstance(100, -1, Image.SCALE_SMOOTH);
DeckLabel = new JLabel(new ImageIcon(scaledInstance));
add(DeckLabel);
}
public void run()
{
Timer timer = new Timer(5000, new ActionListener()
{
#Override
public void actionPerformed(ActionEvent arg0)
{
// Code to be executed
System.out.println("HowareYou");
}
});
timer.setRepeats(false); // Only execute once
timer.start(); // Go go go!
try
{
Thread.sleep(7000);
}
catch(InterruptedException ie)
{
}
}
JLabel DeckLabel;
JPanel DeckPanel;
BufferedImage Deckimg;
}
Utility class used to switch JPanels within the JFrame
package testing;
import java.security.MessageDigest;
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Utility
{
public static void ChangePanel(JPanel jp)
{
testing.Testing.frame.getContentPane().removeAll();
testing.Testing.frame.add(jp);
testing.Testing.frame.validate();
}
}
You're blocking the Swing event thread in SecondPanel.run() with Thread.sleep(7000). This will stop any GUI updates happening. If you remove the sleep you should see the second panel appear before the timer fires.
I have created a appointment calendar which essentially is a JPanel which contains other movable and resizable JPanels all surrounded by a JScrollpane, this all works well and I am able to scroll around the JPanel using the scrollbars correctly. I close to finishing my application but would like to achieve one more thing.
What I would like to do is when a user is moving the appointment (JPanel), when you reach the edge of scrollpane it automatically will scroll at a desired speed. I am confused which existing method or class can do this (if there is one) or if anyone knows of a jar library available out there that will suit my needs?
Is that being lazy? Yeah probably, I guess I should code it myself, if you do agree could someone suggest where I would start? I'm still learning Java and I might need a gentle nudge to keep my code clean and tidy.
If I can provide anymore detail to help with an answer, let me know.
Ok, it's actually not much complicated. You need to call setAutoscroll(true); on your "scrollable" component and add a MouseMotionListener which invokes scrollRectToVisible.
Here is a small example code:
import java.awt.BorderLayout;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class TestImageResize {
protected void initUI() throws MalformedURLException, IOException {
final JFrame frame = new JFrame(TestImageResize.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BufferedImage bi = ImageIO.read(new URL(
"http://www.desktopwallpaperhd.net/wallpapers/19/5/islands-paradise-maldive-nature-background-image-landscape-194469.jpg"));
JPanel panel = new JPanel(new BorderLayout());
JLabel label = new JLabel(new ImageIcon(bi));
panel.add(label);
MouseMotionListener doScrollRectToVisible = new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
((JPanel) e.getSource()).scrollRectToVisible(r);
}
};
panel.addMouseMotionListener(doScrollRectToVisible);
panel.setAutoscrolls(true);
frame.add(new JScrollPane(panel));
frame.pack();
frame.setSize(frame.getWidth() / 2, frame.getHeight() / 2);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new TestImageResize().initUI();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}