This is my first post in this forum and I really hope that it will be answered ASAP. I'm new to Java and loves trying different things often. I thought of making simple balloon message application in Java that pops up at certain time in the system tray conveying different message over time. Just wondering if I could change the text size of the balloon message. Also if somebody can help me out with time intervals and delays for the message to appear and disappear. Below is my code that I tried, please ponder a bit to help me out with this problem.
import java.awt.Image;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import javax.swing.ImageIcon;
public class BubbleMessages {
public static void main(String[] args) throws Exception{
SystemTray tray = SystemTray.getSystemTray();
Image i = new ImageIcon("resources/bulb.gif").getImage();
TrayIcon ti = new TrayIcon(i);
tray.add(ti);
ti.displayMessage("Message", "message", TrayIcon.MessageType.INFO);
}
}
Check the api. The message will automatically disappear with a user click.
If you want to display the message again, you might use Timer
You can modify the code like this
import java.awt.Image;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import javax.swing.ImageIcon;
public class BubbleMessages {
private static TrayIcon ti;
public static void main(String[] args) throws Exception{
SystemTray tray = SystemTray.getSystemTray();
Image i = new ImageIcon("resources/bulb.gif").getImage();
ti = new TrayIcon(i);
tray.add(ti);
MessageDisplayTask mdt = new MessageDisplayTask(ti);
java.util.Timer timer = new java.util.Timer("DM");
timer.schedule(mdt, 0, 10000);//Every three seconds, it shows a message
}
}
class MessageDisplayTask extends java.util.TimerTask {
private TrayIcon ti;
private int displayCount = 0;
public MessageDisplayTask(TrayIcon ti){
this.ti = ti;
}
public void run() {
displayCount++;
if (displayCount <= 10) {
ti.displayMessage("Message", "Message#" + displayCount, TrayIcon.MessageType.INFO);
} else {
//Stop Timer.
this.cancel();
}
}
}
tray.add(ti);
ti.setImageAutoSize(true);
ti.displayMessage("Message", "message", TrayIcon.MessageType.INFO);
Related
I have a problem that the windows cannot pop-up window which setting on the timer. The code below the Block. How can I resolve the problem? Can someone tell me. I very much appreciate it.
I want to get my fortunes to show on the poping window.
When I try this code first, It seems successful, But once. I had never change the code, but it does not work.
I am trying to restart my computer, and I had twice but failed too.
My computer is a system of Windows 10 X64
package systemTray;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.util.List;
import javax.swing.*;
import javax.swing.Timer;
/**
* This program demonstrates the system tray API.
* #version 1.02 2016-05-10
* #author Cay Horstmann
*/
public class SystemTrayTest
{
public static void main(String[] args)
{
SystemTrayApp app = new SystemTrayApp();
app.init();
}
}
class SystemTrayApp
{
public void init()
{
final TrayIcon trayIcon;
if (!SystemTray.isSupported())
{
System.err.println("System tray is not supported.");
return;
}
SystemTray tray = SystemTray.getSystemTray();
Image image = new ImageIcon(getClass().getResource("cookie.png")).getImage();
PopupMenu popup = new PopupMenu();
MenuItem exitItem = new MenuItem("Exit");
exitItem.addActionListener(event -> System.exit(0));
popup.add(exitItem);
trayIcon = new TrayIcon(image, "Your Fortune", popup);
trayIcon.setImageAutoSize(true);
trayIcon.addActionListener(event ->
{
trayIcon.displayMessage("How do I turn this off?",
"Right-click on the fortune cookie and select Exit.",
TrayIcon.MessageType.INFO);
});
try
{
tray.add(trayIcon);
}
catch (AWTException e)
{
System.err.println("TrayIcon could not be added.");
return;
}
//get fortunes to show
final List<String> fortunes = readFortunes();
// I want to pop up window to show message with the timer.
Timer timer = new Timer(10000, event ->
{
int index = (int) (fortunes.size() * Math.random());
trayIcon.displayMessage("Your Fortune", fortunes.get(index),
TrayIcon.MessageType.INFO);
});
timer.start();
}
}
I’ve been trying to make a program that will display a visual metronome that will flash in sync with a MIDI file by sensing a “click” track that I have added using a MIDI editor.
I only have a basic knowledge of Java programming but have been hacking my way through this project. In particular, I’m having problems with the graphical portion. As part of my testing and troubleshooting, I have added a println in a conditional statement that is true when the “click” starts, and this part seems to work well.
The clicks occur about 2 times per second, and each click lasts for about 1/10 of a second. I would like a rectangle shape that is red during the time the click is present, and gray when the click is not present. The attached code actually sorta works (a total hack job I’m sure) , but is one beat off (there is 72 clicks on the MIDI file I’ve been working with, but the JFrame only flashes 71 times).
I suspect the proper way would be to draw a rectangle and somehow change, or update, the fill color in the conditional statements. I’ve spent much time researching this and trying different approaches, but I really have no idea what would be the proper way to proceed.
I would greatly appreciate any guidance and maybe some code snippets.
import java.io.File;
import java.io.IOException;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Transmitter;
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Midi6 extends JPanel implements Receiver
{
private static final int NOTE_ON = 144;
private static final int NOTE_OFF = 128;
int count = 0;
int count2 = 0;
Sequencer sequencer = MidiSystem.getSequencer();
String str = new String();
public Midi6() throws MidiUnavailableException, InvalidMidiDataException, IOException, InterruptedException
{
Sequence sequence = MidiSystem.getSequence(new File("miditest2.mid"));
sequencer.open();
sequencer.setSequence(sequence);
Transmitter transmitter = sequencer.getTransmitter();
transmitter.setReceiver(this);
sequencer.start();
}
public static void main(String[] args) throws InvalidMidiDataException, IOException, MidiUnavailableException, InterruptedException
{
Midi6 midi6 = new Midi6();
JFrame frame1=new JFrame();
frame1.add(midi6);
frame1.setSize(600,100);
frame1.getContentPane().setBackground( Color.LIGHT_GRAY);
frame1.setVisible(true);
}
synchronized public void send(MidiMessage message, long timeStamp)
{
if(message instanceof ShortMessage)
{
ShortMessage sm = (ShortMessage) message;
int channel = sm.getChannel();
if (sm.getCommand() == NOTE_ON)
{
if (channel == 0)
{
setBackground(Color.RED);
count ++;
System.out.println(count);
}
}
else if (sm.getCommand() == NOTE_OFF)
{
if (channel == 0)
{
setBackground(Color.LIGHT_GRAY);
}
}
else
{
}
}
}
#Override
public void close()
{
// TODO Auto-generated method stub
}
}
I'd like to know if it is possible to make a progress bar displayed on the taskbar like Windows Explorer does when there's a file operation going on?
I saw many examples, but they all involved C#.
SWT won't cut it.
I found out that this feature is included in Java 9. It is part of AWT and it is quity simple too use.
Here is short example:
import java.awt.Taskbar;
import java.awt.Taskbar.State;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
/**
* #author fxl
*/
public class TaskbarSample {
public static void main(String[] args) {
// JavaDoc:
// https://docs.oracle.com/javase/9/docs/api/java/awt/Taskbar.html
// MSDNDoc:
// https://msdn.microsoft.com/en-us/library/dd391692(VS.85).aspx
if (Taskbar.isTaskbarSupported() == false) {
return;
}
JFrame dialog = new JFrame("Test - 50%");
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
Taskbar taskbar = Taskbar.getTaskbar();
taskbar.setWindowProgressState(dialog, State.ERROR);
taskbar.setWindowProgressValue(dialog, 50);
}
}
this is now possible using SWT please review the code example:
org.eclipse.swt.snippets.Snippet336
This example will do the job:
Task bar:
Code:
import org.bridj.Platform;
import org.bridj.Pointer;
import org.bridj.cpp.com.COMRuntime;
import org.bridj.cpp.com.shell.ITaskbarList3;
import org.bridj.jawt.JAWTUtils;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TaskBarListDemo extends JFrame implements ActionListener, ChangeListener
{
private ITaskbarList3 list;
private JSlider slider;
private Pointer<?> hwnd;
private TaskBarListDemo() throws ClassNotFoundException
{
super("TaskbarList Demo (" + (Platform.is64Bits() ? "64 bits" : "32 bits") + ")");
list = COMRuntime.newInstance(ITaskbarList3.class);
getContentPane().add("Center", new JLabel("Hello Native Windows 7 World !"));
Box box = Box.createVerticalBox();
int min = 0;
int max = 300;
int val = (min + max / 2);
slider = new JSlider(min, max, val);
slider.addChangeListener(this);
box.add(slider);
ButtonGroup group = new ButtonGroup();
for (ITaskbarList3.TbpFlag state : ITaskbarList3.TbpFlag.values())
{
JRadioButton cb = new JRadioButton(state.name());
group.add(cb);
cb.putClientProperty(ITaskbarList3.TbpFlag.class, state);
cb.setSelected(state == ITaskbarList3.TbpFlag.TBPF_NORMAL);
cb.addActionListener(this);
box.add(cb);
}
getContentPane().add("South", box);
}
#Override
protected void finalize() throws Throwable
{
super.finalize();
list.Release();
}
public void setVisible(boolean visible)
{
super.setVisible(visible);
long hwndVal = JAWTUtils.getNativePeerHandle(this);
hwnd = Pointer.pointerToAddress(hwndVal);
list.SetProgressValue((Pointer) hwnd, slider.getValue(), slider.getMaximum());
}
#Override
public void stateChanged(ChangeEvent actionEvent)
{
list.SetProgressValue((Pointer) hwnd, slider.getValue(), slider.getMaximum());
}
#Override
public void actionPerformed(ActionEvent actionEvent)
{
JRadioButton button = ((JRadioButton) actionEvent.getSource());
if (button.isSelected())
{
ITaskbarList3.TbpFlag flag = (ITaskbarList3.TbpFlag) button.getClientProperty(ITaskbarList3.TbpFlag.class);
list.SetProgressValue((Pointer) hwnd, slider.getValue(), slider.getMaximum());
list.SetProgressState((Pointer) hwnd, flag);
}
}
public static void main(String[] arguments) throws Exception
{
TaskBarListDemo f = new TaskBarListDemo();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
}
Maven dependencies:
<dependencies>
<dependency>
<groupId>com.nativelibs4java</groupId>
<artifactId>bridj</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>LATEST</version>
</dependency>
</dependencies>
There is no standard facility in Java for doing so, yet.
Hence you need to talk to Windows directly to do that. So you need to locate the correct Windows routine, and use JNA (probably the easiest) to invoke that routine. I do not know of a vendor or a project who has done this already.
Edit: It appears that the http://code.google.com/p/nativelibs4java/ project may do what you want.
As Java9's java.awt.Taskbar only works for old swing frames (they somehow forgot to implement this for javafx.stage.Stage) and com.nativelibs4java bridj isn't working (anymore) (see https://github.com/nativelibs4java/BridJ/issues/94) I implemented a solution using JNA 4.1.0.
Please note:
Relies on calling internal javafx api (com.sun.javafx.stage.WindowHelper) - so it might break with the next java update
It only sets the "indeterminate" progress state - but normal progress state should be possible too with some adjustments
Hope this helps.
ITaskbarList3.java
package example;
import com.sun.jna.platform.win32.Guid.IID;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinNT.HRESULT;
public interface ITaskbarList3 {
IID IID_ITASKBARLIST3 = new IID("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf"); // from ShObjIdl.h
int TBPF_NOPROGRESS = 0;
int TBPF_INDETERMINATE = 0x1;
int TBPF_NORMAL = 0x2;
int TBPF_ERROR = 0x4;
int TBPF_PAUSED = 0x8;
HRESULT SetProgressState(HWND hwnd, int tbpFlags);
}
TaskbarList3.java
package example;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinNT.HRESULT;
import com.sun.jna.platform.win32.COM.COMInvoker;
public final class TaskbarList3 extends COMInvoker implements ITaskbarList3 {
public TaskbarList3(Pointer pointer) {
setPointer(pointer);
}
#Override
public HRESULT SetProgressState(HWND hwnd, int tbpFlags) {
return (HRESULT) this._invokeNativeObject(
10, // magic number (gathered by trial and error)
new Object[] { this.getPointer(), hwnd, tbpFlags },
HRESULT.class);
}
}
TaskbarPeer.java
package example;
import com.sun.javafx.stage.WindowHelper;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Guid.CLSID;
import com.sun.jna.platform.win32.Ole32;
import com.sun.jna.platform.win32.W32Errors;
import com.sun.jna.platform.win32.WTypes;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.ptr.PointerByReference;
import javafx.stage.Stage;
public final class TaskbarPeer {
public static void setIndeterminateProgress(Stage stage, boolean indeterminate) {
final var peer = WindowHelper.getPeer(stage);
final long windowHandle = peer.getRawHandle();
final var clsid = new CLSID("56FDF344-FD6D-11d0-958A-006097C9A090"); // from ShObjIdl.h
final var taskbarListPointerRef = new PointerByReference();
var hr = Ole32.INSTANCE.CoCreateInstance(clsid, null, WTypes.CLSCTX_SERVER,
ITaskbarList3.IID_ITASKBARLIST3, taskbarListPointerRef);
if (W32Errors.FAILED(hr)) {
throw new RuntimeException("failed with code: " + hr.intValue());
}
final TaskbarList3 taskbarList = new TaskbarList3(taskbarListPointerRef.getValue());
final var hwnd = new HWND(new Pointer(windowHandle));
final int progressState = indeterminate ? ITaskbarList3.TBPF_INDETERMINATE : ITaskbarList3.TBPF_NOPROGRESS;
hr = taskbarList.SetProgressState(hwnd, progressState);
if (W32Errors.FAILED(hr)) {
throw new RuntimeException("failed with code: " + hr.intValue());
}
}
}
Sample.java
package example;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
public final class Sample extends Application {
private boolean indeterminateProgressState = false;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
final Button btn = new Button("Click me!");
primaryStage.setScene(new Scene(btn));
primaryStage.sizeToScene();
primaryStage.show();
btn.setOnAction(evt -> {
indeterminateProgressState = !indeterminateProgressState;
TaskbarPeer.setIndeterminateProgress(primaryStage, indeterminateProgressState);
});
}
}
Windows exposes this through COM. I am sure a "flat DLL" call would be easier for you, but if you can get to COM you can do this. The COM interface is ITaskbarList3 (there is also an ITaskbarList4 you can use that inherits from it.) http://msdn.microsoft.com/en-us/library/dd391692(VS.85).aspx documents it. SetProgressState and SetProgressValue are the methods you will want to invoke. State is normal (green), paused (yellow), error (red), indeterminate (swooshing green) and none. On the MSDN page some community people have added details of calling this COM component from VB and C# - that might help you figure out the setup and tear down required from Java.
EDIT: Everything displays correctly when either field or hunterField hold no objects in any location. field and hunterField both exclusively hold objects which extend the same class, so I guess it may have something to do with inheritance...?
I have created a simple Agent-Based Model using MASON. The back-end works find, but when I try displaying my agents only "wall" agents are displayed. (Wall Portrayal) My code is below... Any idea?
package sim.app.celai;
import java.awt.Color;
import javax.swing.JFrame;
import sim.app.tutorial3.Tutorial3WithUI;
import sim.display.Controller;
import sim.display.Display2D;
import sim.display.GUIState;
import sim.portrayal.grid.SparseGridPortrayal2D;
import sim.util.Bag;
public class FieldWithGUI extends GUIState {
public Display2D display;
public JFrame frame;
SparseGridPortrayal2D hunterPortrayal = new SparseGridPortrayal2D();
SparseGridPortrayal2D wallPortrayal = new SparseGridPortrayal2D();
SparseGridPortrayal2D childPortrayal = new SparseGridPortrayal2D();
public FieldWithGUI() {
super(new Field(System.currentTimeMillis()));
}
public void setupPortrayals() {
childPortrayal.setField(((Field) state).field);
hunterPortrayal.setField(((Field) state).hunterField);
wallPortrayal.setField(((Field) state).wallField);
childPortrayal.setPortrayalForAll(new sim.portrayal.simple.OvalPortrayal2D(Color.blue));
hunterPortrayal.setPortrayalForAll(new sim.portrayal.simple.OvalPortrayal2D(Color.red));
wallPortrayal.setPortrayalForAll(new sim.portrayal.simple.OvalPortrayal2D(Color.green));
display.reset();
display.repaint();
}
public void quit()
{
super.quit();
if (frame!=null) frame.dispose();
frame = null; // let gc
display = null; // let gc
}
public static void main(String[] args)
{
new FieldWithGUI().createController();
}
public void start()
{
super.start();
// set up our portrayals
setupPortrayals();
}
public void init(Controller c)
{
super.init(c);
// Make the Display2D. We'll have it display stuff later.
display = new Display2D(400,400,this); // at 400x400, we've got 4x4 per array position
frame = display.createFrame();
c.registerFrame(frame); // register the frame so it appears in the "Display" list
frame.setVisible(true);
// specify the backdrop color -- what gets painted behind the displays
display.setBackdrop(Color.black);
// attach the portrayals
display.attach(childPortrayal, "children");
display.attach(hunterPortrayal, "hunter");
display.attach(wallPortrayal, "wall");
}
}
Please have a look at the following code
import com.sun.jna.Native;
import uk.co.caprica.vlcj.binding.LibVlc;
import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
import com.sun.jna.NativeLibrary;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.bean.playerbean.MediaPlayer;
import uk.co.caprica.vlcj.player.MediaPlayerEventAdapter;
import uk.co.caprica.vlcj.player.MediaPlayerEventListener;
public class PlayMedia extends JFrame
{
private EmbeddedMediaPlayerComponent m;
private JProgressBar bar;
public PlayMedia()
{
NativeLibrary.addSearchPath(
RuntimeUtil.getLibVlcLibraryName(), "c:\\program files\\videolan\\vlc"
);
Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
m = new EmbeddedMediaPlayerComponent();
m.getMediaPlayer().addMediaPlayerEventListener(new UpdateBar());
bar = new JProgressBar(0,100);
bar.setStringPainted(true);
getContentPane().add(m);
getContentPane().add(bar,"South");
this.setSize(500,500);
this.validate();
this.setLocationRelativeTo(null);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
m.getMediaPlayer().playMedia("C:\\Users\\Yohan\\Desktop\\video.avi");
}
private class UpdateBar extends MediaPlayerEventAdapter
{
public void positionChanged(MediaPlayer mp, float pos)
{
int value = Math.min(100, Math.round(pos * 100.0f));
bar.setValue(value);
}
}
public static void main(String[]args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new PlayMedia();
}
});
}
}
In here, video is playing fine, but the progress bar is not getting updated. How to update the progress bar as the video plays? Please help!
I haven't used ProgressBars in Swing, but I have used them in Silverlight, so I would think most of the principles would be the same. Check out the answer to my question here:
How do I make a Silverlight Progressbar update according to its value? It may not show you exactly how to do this in Swing, but it doesn't seem like you're using threading in your code, which is what my problem was.
for some unknown reason positionChanged() isn't called during the video.
try to use timeChanged() istead, it worked for me!
public void positionChanged (MediaPlayer mediaPlayer , long time) { ... }