Reminder using JOptionPane - java

I am designing one reminder type application using java swing.
In this I am giving two options to user, using JOptionPane YES_NO_OPTION. But what i want is if user not given any input within 10 minutes it should choose YES as default option.
what i have to do for that?
Please check below code...
public void snooze()
{
int action = JOptionPane.showConfirmDialog(null, "Yes = close citrix and Aventail \n No = snooze after 30min", "Close", JOptionPane.YES_NO_OPTION);
if(action == 0){
killcitrix();
endaventail();
}
else{
JOptionPane.showMessageDialog(null, "Will snooze after 30min");
try {
TimeUnit.SECONDS.sleep(30);
} catch (InterruptedException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
snooze();
}
}

As user1803551 already mentioned, use a Timer. Here is an example:
after 10 seconds of inactivity (if the user didn't press any button), the dialog will automatically dispose and the selected option will be JOptionPane.YES_OPTION
If the user pressed 'No', a new JOptionPane with the same functionalities will appear after 5 seconds.
Preview
Code:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.Timer;
import javax.swing.border.TitledBorder;
public class Example {
private int choice;
private JTextArea log;
public Example() {
log = new JTextArea();
log.setEditable(false);
JFrame frame = new JFrame();
frame.add(log);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
showConfirmDialog(frame);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Example();
}
});
}
public void showConfirmDialog(Component parent) {
Timer timer = new Timer(0, null);
Timer timer2 = new Timer(0, null);
log.append("Will automatically press 'Yes' after 10 seconds.\n");
timer.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Window window : Window.getWindows()) {
if (window instanceof JDialog) {
JDialog dialog = (JDialog) window;
if (dialog.getContentPane().getComponentCount() == 1
&& dialog.getContentPane().getComponent(0) instanceof JOptionPane
&& dialog.getTitle().equals("Dialog")) {
dialog.dispose();
choice = JOptionPane.YES_OPTION;
log.append("Programmatically pressed 'Yes' on the JOptionPane due to inactivity of user\n");
}
}
}
timer.stop();
timer2.stop();
}
});
timer.setInitialDelay(10 * 1000);
timer.start();
choice = JOptionPane.showConfirmDialog(parent, "", "Dialog", JOptionPane.YES_NO_CANCEL_OPTION);
if (choice == JOptionPane.NO_OPTION) {
log.append("Dialog will reappear in 5 seconds\n");
timer2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
log.append("Dialog reappeared\n");
showConfirmDialog(parent);
timer2.stop();
}
});
timer2.setInitialDelay(5 * 1000);
timer2.start();
}
timer.stop();
}
}

Related

Java : Timer get paused by PopupMenu

Hi,
I'm working on a small program in Java that have 2 things :
An always-on-top JWindow with a refresh Timer (there can be more than one JWindow)
A TrayIcon with a PopupMenu on left click
The PopupMenu is opened with a MouseEventListener and with a dummy Frame as parent (needed).
Runnable example :
import java.awt.AWTException;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JWindow;
import javax.swing.Timer;
public class TestWindow extends JWindow {
private int color;
public static Image createImage(String path) {
URL imageURL = TestWindow.class.getResource(path);
if (imageURL == null) {
System.err.println("Resource not found: " + path);
return null;
} else {
return (new ImageIcon(imageURL)).getImage();
}
}
public static void main(String[] args) {
addTrayIcon();
new TestWindow();
}
public static void addTrayIcon(){
if (!SystemTray.isSupported()) {
System.out.println("SystemTray is not supported");
System.exit(0);
}
TrayIcon trayIcon = new TrayIcon(createImage("/icon.png"));
trayIcon.setImageAutoSize(true);
PopupMenu popup = new PopupMenu();
popup.add(new MenuItem("test"));
popup.add(new MenuItem("test"));
popup.add(new MenuItem("test"));
Frame frame = new Frame("MiniMario");
frame.setResizable(false);
frame.setUndecorated(true);
frame.setType(Frame.Type.UTILITY);
frame.setAlwaysOnTop(true);
frame.setAutoRequestFocus(true);
frame.add(popup);
frame.setVisible(false);
frame.addFocusListener(new FocusListener(){
#Override
public void focusGained(FocusEvent e) {
frame.setVisible(false);
}
#Override
public void focusLost(FocusEvent e) {
frame.setVisible(false);
}
});
trayIcon.addMouseListener(new MouseListener(){
#Override
public void mouseClicked(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON3){
EventQueue.invokeLater(new Runnable(){
#Override
public void run() {
frame.setVisible(true);
popup.show(frame, e.getXOnScreen(), e.getYOnScreen());
}
});
}
}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
});
final SystemTray tray = SystemTray.getSystemTray();
try {
tray.add(trayIcon);
} catch (AWTException e) {
System.out.println("TrayIcon could not be added.");
System.exit(0);
}
}
public TestWindow(){
this.setBackground(new Color(0,0,0));
this.setLocationRelativeTo(null);
this.setSize(100, 100);
color = 0;
Timer refresh = new Timer(10,new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
color+=10;
setAlwaysOnTop(true);
getContentPane().setBackground(new Color(color%256,color%256,color%256));
}
});
this.setVisible(true);
refresh.start();
}
}
Here is the thing : when I open the PopupMenu, it freeze the JWindow. I figured out that it was the refresh timer not running anymore. I already tried the following :
Giving up on the always-on-top
Showing the PopupMenu in a runnable (new Thread(...).start / SwingUtilities.invokeLater / EventQueue.invokeLater)
Replacing the JWindow Swing Timer by a Thread with an infinite loop and Thread.sleep
Using the native TrayIcon.setPopup (it was originally the case)
Use the JWindow or the Frame setModalExclusionType (see below)
After searching for this kind of problem, few were linked to swing modality but I don't get how to use modality on this setup because neither Frame nor PopupMenu have the setModal I saw on another post. Do I have to make my own PopupMenu out of a JDialog ?
(Sorry for my bad english)
Thank you for your time
EDIT : Runnable example

Message box without any buttons at all

I want to create auto-disposing message dialog. Everything works beside that there is still an ok button to click.
I want to get read the button.
Please check out this code -> works perfectly:
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class CloseOptionPane {
#SuppressWarnings("serial")
private static void createAndShowGui() {
final JLabel label = new JLabel();
int timerDelay = 1000;
new Timer(timerDelay, new ActionListener() {
int timeLeft = 3;
#Override
public void actionPerformed(ActionEvent e) {
if(timeLeft > 0) {
label.setText("Human player. It is your move!");
timeLeft--;
} else {
((Timer) e.getSource()).stop();
Window win = SwingUtilities.getWindowAncestor(label);
win.setVisible(false);
}
}
}) {
{
setInitialDelay(0);
}
}.start();
JOptionPane.showMessageDialog(null, label);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

How to loop a sound while button is pressed and stop when released?

I've tried to search similiar question to this, but couldn't find. I don't know how i can stop my sound when button is released, and also, i don't know how to loop sound only one by one, when i hold button it plays again while previous loop is still playing, and the sound is becoming a loop from ∞ sounds.
Here's the code:
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Component;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.net.MalformedURLException;
import java.util.ArrayList;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class test {
String b[]={"Q","W","E","R","T","Y","U","I","O","P","A","S","D","F","G","H","J","K","L","Z","X","C","V","B","N","M"};
Action[] actions = new AbstractAction[26];
public test() throws Exception {
JFrame frame = new JFrame();
JButton[] buttons = new JButton[26];
for(int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton(b[i]);
buttons[i].setSize(80, 80);
buttons[i].addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
System.out.println(e.getKeyChar());
playSound(new File("loopbase/loop1/"+e.getKeyChar()+".wav"));
}
public void keyReleased(KeyEvent e){
}
});
frame.add(buttons[i]);
}
JPanel contentPane = (JPanel)frame.getContentPane();
frame.setLayout(new GridLayout(3, 5, 5, 3));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
try {
new test();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
public void playSound(File soundName)
{
try
{
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundName.getAbsoluteFile( ));
Clip clip = AudioSystem.getClip( );
clip.open(audioInputStream);
clip.start( );
}
catch(Exception ex)
{
System.out.println("Error with playing sound.");
ex.printStackTrace( );
}
}
}
Anyone can help me with this issue?
I don't know how i can stop my sound when button is released?
You can stop the the clip by using DataLine#stop(). Just keep the reference of last played clip and call below line to stop it.
clip.stop();
Note: You can store it somewhere in static variable.
Sample code:
private static Clip clip;
...
public void keyReleased(KeyEvent e) {
if (clip != null) {
clip.stop();
}
}
...
public void playSound(File soundName) {
...
clip = AudioSystem.getClip();
...
}
When I hold the Button it plays again while previous loop is still playing.
This is because for every keyPress you are creating a new File object. That should be avoided.
To stop sound:
I would add a boolean parameter to playsound method. And depending upon the parameter passed I would call clip.start() or clip.stop() (superclass DataLine has a stop method) .
Call playsound(filename,false); in keyReleased.
public void playSound(File soundName , boolean start)
{
try
{
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundName.getAbsoluteFile( ));
Clip clip = AudioSystem.getClip( );
clip.open(audioInputStream);
if(start == true)
clip.start();
else
clip.stop();
}
catch(Exception ex)
{
System.out.println("Error with playing sound.");
ex.printStackTrace( );
}
}

Why done() is not called until modal dialog closed?

In an example below, an attempt made to open dialog on worker start and to close it on worker end.
Unfortunately, done() is not executed until dialog closed manually.
Why?
package tests.javax.swing;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Try_SwingWorker_Modality {
private static final Logger log = LoggerFactory.getLogger(Try_SwingWorker_Modality.class);
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
AbstractAction popupAction = new AbstractAction("popup") {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "popup");
}
};
final JDialog dialog = new JDialog((JFrame)null, true);
dialog.setLayout(new FlowLayout());
dialog.add(new JButton(popupAction));
dialog.pack();
dialog.setLocationRelativeTo(null);
SwingWorker<Object,Object> swingWorker = new SwingWorker<Object,Object>() {
#Override
protected Object doInBackground() throws Exception {
log.debug("doInBackground()");
return null;
}
#Override
protected void done() {
log.debug("done");
//dialog.dispose();
}
};
swingWorker.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
log.debug("event = {}", evt);
if( "state".equals(evt.getPropertyName())) {
if( SwingWorker.StateValue.STARTED == evt.getNewValue() ) {
dialog.setVisible(true);
log.debug("after setVisible()");
}
else if( SwingWorker.StateValue.DONE == evt.getNewValue() ) {
dialog.dispose();
}
}
}
});
swingWorker.execute();
}
});
}
}
You're freezing your SwingWorker's PropertyChangeListener with that code. I would never set the dialog visible from within the PCL.
Rather, I'd do it here:
swingWorker.execute();
dialog.setVisible(true);

Adding copy action in windows to java app

I want to get the event like crtl+c or right click copy in windows , that could do the event to java application running ,
that means if someone copies some text , that should be pasted into the java application textarea...
i have made the java application and it can accept arguments through main method.
but how to trigger event from windows to java..
The simplest way is to monitor changes to the Toolkit.getSystemClipboard
There are two ways to do this. You can monitor changes to the DataFlavour, but this will only help if the data flavor changes, not the content and/or you could monitor the contents of the clipboard and update your view when it's content changes...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.FlavorEvent;
import java.awt.datatransfer.FlavorListener;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ClipboardMonitor {
public static void main(String[] args) {
new ClipboardMonitor();
}
public ClipboardMonitor() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextArea textArea;
public TestPane() {
textArea = new JTextArea(10, 10);
setLayout(new BorderLayout());
add(new JScrollPane(textArea));
Toolkit.getDefaultToolkit().getSystemClipboard().addFlavorListener(new FlavorListener() {
#Override
public void flavorsChanged(FlavorEvent e) {
setText(getClipboardContents());
}
});
Thread t = new Thread(new ContentsMonitor());
t.setDaemon(true);
t.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected String getClipboardContents() {
String text = null;
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) {
try {
Transferable contents = clipboard.getContents(TestPane.this);
text = (String) contents.getTransferData(DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException | IOException ex) {
ex.printStackTrace();
}
}
return text;
}
protected void setText(final String text) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
textArea.setText(text);
}
});
}
public class ContentsMonitor implements Runnable {
#Override
public void run() {
String previous = getClipboardContents();
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
String text = getClipboardContents();
if (text != null && !text.equals(previous)) {
setText(text);
previous = text;
}
}
}
}
}
}

Categories