I am very new to Java, and I wanted to try to make a thing in BlueJ that requires BlueJ to know when the mouse is clicked, and to be able to determine the mouse's coordinates on the x,y plane.
In my class where I code, I have seen some imported class and things like Scanner and Graphics, so it might be something along those lines, but I am not sure.
I just mainly need
The thing to import (if it is a thing that needs to be imported)
How to make it tell if the mouse is clicked
How to make it be able to tell me the x, y position of the mouse when asked (like, what class method would I have to refer to to find this)
After I have that, I will work with that to try to make my program. Thank you!
EDIT: Upon request, here is my attempt
java.awt.event.MouseAdapter
public class main
{
MouseAdapter test = new MouseAdapter();
}
public void mouseMoved(test e)
{
System.out.println("hey your mouse moved");
}
I am clearly doing something horribly wrong
One way to achieve your goal would be to use java swing. The following code will print out a statement if the mouse is moved inside the created window:
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame jFrame = new JFrame();
jFrame.setSize(720,480);
jFrame.setVisible(true);
jFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jFrame.getContentPane().addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent mouseEvent) {
System.out.println("STUFF");
}
#Override
public void mouseMoved(MouseEvent mouseEvent) {
System.out.println("STUFF");
}
});
});
}
This is not an ideal solution but I hope it helps you to look in the right direciton.
I have a song library, and I would like this selection list to only be on the left hand side of the window because I want to put other information about the song on the righthand side. I'm not sure how to change the size of JScrollPane, which is inside the JFrame.
In this library, I want to be able to import the songs stored in a file to my song library. Right now, I have an array within my code, but I want to be able to read from a text file instead of using this approach. In the file, I want to be able to store artist and album information about the song, but I don't want it to display in the song list.
String songs[] = {"Song1", "Song2", "Song3", "Song4", "Song5"};
JList list = new JList(songs);
public SongLib(){
JFrame songLibrary = new JFrame("Song Library");
songLibrary.setLocationRelativeTo(null);
songLibrary.setResizable(true);
songLibrary.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
list.addListSelectionListener(new ListSelectionListener(){
public void valueChanged(ListSelectionEvent evt){
int i = list.getSelectedIndex();
if (i != -1)
System.out.println("Selected: " + songs[i]);
else
System.out.println("Choose a song");
}
});
JScrollPane JSPane = new JScrollPane(list);
JSPane.setPreferredSize(new Dimension(100,100));
songLibrary.add(JSPane);
songLibrary.setSize(400,400);
songLibrary.setVisible(true);
}
public static void main(String[] args){
new SongLib();
}
Stop calling (for the rest of your entire life) setPreferredSize(). Meaning that this call: JSPane.setPreferredSize(new Dimension(100,100)); should definitely be removed.
If you want to have 2 panels side-by-side with a draggable separator: use JSplitPane. If you don't want the draggable divider, use a JPanel with an appropriate LayoutManager (GridBagLayout may be a good choice)
Reading from a file is pretty easy, just make a search on SO and you will find hundreds of response. If you want to parse csv-files, there are some libraries around that can help you do that. Eventually, if you consider making this an application for a while, there are some small pure-java, embeddable, databases which will do a much better job at reading/storing/searching information than a simple text-file.
Learn the Java naming conventions and stick to them: variables always start with a lower-case letter.
In addition to #Guillaume Polet's good advice, setVisibleRowCount() may be useful to you going forward.
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
/** #see https://stackoverflow.com/a/14801908/230513 */
public class SongLib {
String songs[] = {"Song1", "Song2", "Song3", "Song4", "Song5"};
JList list = new JList(songs);
public SongLib() {
JFrame songLibrary = new JFrame("Song Library");
songLibrary.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
list.setVisibleRowCount(4);
list.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent evt) {
int i = list.getSelectedIndex();
if (i != -1) {
System.out.println("Selected: " + songs[i]);
} else {
System.out.println("Choose a song");
}
}
});
JScrollPane JSPane = new JScrollPane(list);
songLibrary.add(JSPane);
songLibrary.pack();
songLibrary.setLocationRelativeTo(null);
songLibrary.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new SongLib();
}
});
}
}
For 1., take a look at layouting in Java, especially the GridBagLayout.
http://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
For 2: Reading and writing from / into files is made by using File-Objects and Inout/Output-Streams. But this is a very low level way to do this.
I think you should consider using an XML file. Take a look at JAXB
I am learning Java Program for Mobile, I am trying to create a program thru which I can show images on screen by dragging from left to right, or right to left.
I have touch screen mobile, no harrdware keyboard.
I am trying the below code in which I have two forms and I want to show the other form when I swip the fingure on screen.
import java.io.IOException;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class ImageDisplay extends MIDlet{
private Display display;
private Form form1,form2;
private Image myImage1,myImage2;
public void startApp(){
display = Display.getDisplay(this);
form1 = new Form ("Image Display");
form2 = new Form("Second Image");
try {
myImage1 = Image.createImage("/bgscaled.jpg");
myImage2 = Image.createImage("/spla77sh.jpg");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
form1.append(myImage1);
form2.append(myImage2);
display.setCurrent(form1);
display.setCurrent(form2);
}
public void pauseApp(){
}
public void destroyApp(boolean unconditional){
notifyDestroyed();
}
}
You do not have a way to be notified by an LCDUI Form when a screen swipe happens.
You can add "Next" and "Previous" buttons and change the forms when the buttons are clicked.
You will need to use Canvas instead of the Form screens as Canvas has various methods (e.g., pointerDragged) that can be used to determine touch, release and dragging actions.
Using Canvas can be a lot of work though (because your code will be responsible for every pixel that is drawn on the display). However, you may find J2ME Polish useful to transfer your Form UI to Canvas. (I'm not sure, but J2ME Polish might also take care of the swiping behaviour you are looking for, too.)
I am using a JColorchooser at various places in an application. There can be multiple instances of the panel that can invoke a JColorChooser.
The "Swatches" panel in the chooser has an area of "recent" colors, which only persists within each instance of JColorChooser. I would like to (a) have the same "recent" colors in all my choosers in my application, and (b) to save the colors to disk so that these colors survive close and restart of the application.
(At least (a) could be solved by using the same single chooser instance all over the whole app, but that apears cumbersome because I would need to be very careful with attached changelisteners, and adding/removing the chooser panel to/from various dialogs.)
I did not find any method that lets me set (restore) these "recent" colors in the chooser panel. So to me, it appears that the only ways of achieving this would be:
serialize and save / restore the whole chooser (chooser panel?)
or
create my own chooser panel from scratch
Is this correct, or am I missing something?
BTW: I would also like to detect a double click in the chooser, but it seems hard to find the right place to attach my mouse listener to. Do I really need to dig into the internal structure of the chooser panel to do this? (No, it does not work to detect a second click on the same color, because the change listener only fires if a different color is clicked.)
As you noticed, there is no public api to access the recent colors in the DefaultSwatchChooserPanel, even the panel itself isn't accessible.
As you'll need some logic/bean which holds and resets the recent colors anyway (plus the extended mouse interaction), rolling your own is the way to go. For some guidance, have a look at the implementation of the swatch panel (cough ... c&p what you need and modify what you don't). Basically, something like
// a bean that keeps track of the colors
public static class ColorTracker extends AbstractBean {
private List<Color> colors = new ArrayList<>();
public void addColor(Color color) {
List<Color> old = getColors();
colors.add(0, color);
firePropertyChange("colors", old, getColors());
}
public void setColors(List<Color> colors) {
List<Color> old = getColors();
this.colors = new ArrayList<>(colors);
firePropertyChange("colors", old, getColors());
}
public List<Color> getColors() {
return new ArrayList<>(colors);
}
}
// a custom SwatchChooserPanel which takes and listens to the tracker changes
public class MySwatchChooserPanel ... {
ColorTracker tracker;
public void setColorTracker(....) {
// uninstall old tracker
....
// install new tracker
this.tracker = tracker;
if (tracker != null)
tracker.addPropertyChangeListener(.... );
updateRecentSwatchPanel()
}
/**
* A method updating the recent colors in the swatchPanel
* This is called whenever necessary, specifically after building the panel,
* on changes of the tracker, from the mouseListener
*/
protected void updateRecentSwatchPanel() {
if (recentSwatchPanel == null) return;
recentSwatchPanel.setMostRecentColors(tracker != null ? tracker.getColors() : null);
}
// the mouseListener which updates the tracker and triggers the doubleClickAction
// if available
class MainSwatchListener extends MouseAdapter implements Serializable {
#Override
public void mousePressed(MouseEvent e) {
if (!isEnabled())
return;
if (e.getClickCount() == 2) {
handleDoubleClick(e);
return;
}
Color color = swatchPanel.getColorForLocation(e.getX(), e.getY());
setSelectedColor(color);
if (tracker != null) {
tracker.addColor(color);
} else {
recentSwatchPanel.setMostRecentColor(color);
}
}
/**
* #param e
*/
private void handleDoubleClick(MouseEvent e) {
if (action != null) {
action.actionPerformed(null);
}
}
}
}
// client code can install the custom panel on a JFileChooser, passing in a tracker
private JColorChooser createChooser(ColorTracker tracker) {
JColorChooser chooser = new JColorChooser();
List<AbstractColorChooserPanel> choosers =
new ArrayList<>(Arrays.asList(chooser.getChooserPanels()));
choosers.remove(0);
MySwatchChooserPanel swatch = new MySwatchChooserPanel();
swatch.setColorTracker(tracker);
swatch.setAction(doubleClickAction);
choosers.add(0, swatch);
chooser.setChooserPanels(choosers.toArray(new AbstractColorChooserPanel[0]));
return chooser;
}
As to doubleClick handling: enhance the swatchChooser to take an action and invoke that action from the mouseListener as appropriate.
You can use the JColorChooser.createDialog method - one of the parameters is a JColorChooser. Use a static instance of the JColorChooser and make it the Dialog modal - that way, only one color chooser is displayed at a time.
The createDialog method also takes ActionListeners as parameters for the OK and Cancel button. Thus, don't really have to manage listeners. Of course, this doesn't persist the recent colors across invocations of the app, just persists recent colors in the current app.
Here's a workaround using reflection - it will work provided the underlying implementation doesn't change. Assuming you have a JColorChooser, add your recent colors to it like this:
final JColorChooser chooser = new JColorChooser(Color.white);
for (AbstractColorChooserPanel p : chooser.getChooserPanels()) {
if (p.getClass().getSimpleName().equals("DefaultSwatchChooserPanel")) {
Field recentPanelField = p.getClass().getDeclaredField("recentSwatchPanel");
recentPanelField.setAccessible(true);
Object recentPanel = recentPanelField.get(p);
Method recentColorMethod = recentPanel.getClass().getMethod("setMostRecentColor", Color.class);
recentColorMethod.setAccessible(true);
recentColorMethod.invoke(recentPanel, Color.BLACK);
recentColorMethod.invoke(recentPanel, Color.RED);
//add more colors as desired
break;
}
}
I need to implement a class, using Swing, which can obtain the mouse coordinates when the user clicks anywhere on the screen. if I wanted to obtain the mouse coordinates inside my own window, I'd use a MouseListener, but I want it to work even when the user clicks outside my program.
I want my class to behave just like KColorChooser: the user clicks on the drop button and he can click anywhere on the screen to obtain the color of that spot. but I don't know if that's possible using pure Java.
It is possible though limited:
Add an AWTEventListener for focus events. As long as your app has focus before the button is clicked you'll receive a focus lost event. Then query for the pointer position.
The limitation is that, of course, your app loses focus. So depending on what you are ultimately trying to achieve this might not be useful.
If you don't want to lose focus then you will have to temporarily take a screenshot of the whole screen and display that in a screen filling window which listens for a mouse click as usual.
Proof of first method:
import java.awt.AWTEvent;
import java.awt.MouseInfo;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import javax.swing.JFrame;
public class Application1 {
public static void main(String[] args) {
Toolkit.getDefaultToolkit().addAWTEventListener(
new Listener(), AWTEvent.MOUSE_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static class Listener implements AWTEventListener {
public void eventDispatched(AWTEvent event) {
System.out.print(MouseInfo.getPointerInfo().getLocation() + " | ");
System.out.println(event);
}
}
}
Clicking outside of the app produced:
java.awt.Point[x=198,y=59] | java.awt.event.MouseEvent[MOUSE_EXITED, ...
java.awt.Point[x=976,y=503] | java.awt.FocusEvent[FOCUS_LOST, ...
The second point is outside of the app.
Forget about GlassPane, there's another 100% native Java way to do it that works both on OS X and on Windows.
Java has always supported translucency for its windows on OS X and Java now supports translucency for its windows on Windows too (since Java 1.6.0_10 or so, needs to be checked).
So the trick is: upon clicking on the "pick a color" tool, you create a nearly transparent borderless Java window covering the entire screen. You set its alpha to 10 (alpha goes from 0 to 255). That alpha is so low the user won't notice that there's a very thin "nearly transparent but only very very very translucent" borderless window covering the entire screen.
Now when the user clicks on your "alpha set to 10 translucent borderless window" covering the entire screen, you get your (x,y).
Discard the borderless Java window.
Use Robot's getRgb(x,y) and you're done.
Why set the alpha to 10 and not 0? Because otherwise clicks aren't intercepted by Java but go directly to the OS (at least that's how it works for a fact on OS X). There's a treshold and I know it's not set at '1', nor '2', it's around 10 or so.
EDIT I just realized you know need to pick several colors, this is trickier but can still be done using 100% Java. Either you can live with "slightly off" colors (affected by the "nearly transparent" 'invisible' layer) or upon getting a click you must remove the layer, get the correct pixel color, and put again a "nearly transparent" layer. Now of course that is one heck of a hack but it can be done in 100% Java.
Use
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
PointerInfo inf = MouseInfo.getPointerInfo();
Point p = inf.getLocation();
p.x and p.y will give you co-ordinates outside your window.
I don't know if that's possible using
pure Java.
Its not possible using pure Java, since Java is only aware of MouseEvents on Windows belonging to Java.
These events are directed to the window which has the focus, from all events on the desktop you can only get the mouse position.
As already shown by Keilly it's only possible to get the mouse postion.
You need to include a native lib
I haven't tried this myself, but maybe you could create a full-screen, transparent panel/frame/etc, and add a MouseListener to that.
It is possible with a little trick. Should be 100% cross-platform (tested on Linux & Windows). Basically, you create a small JWindow, make it "alwaysOnTop" and move it around with the mouse using a timer.
For details, see my answer here.
The location (x,y) and the time interval
(d) between each click is supplied thru command line arguments. Here is the
program
import java.awt.* ;
import java.util.* ;
public final class ClickMouse extends TimerTask {
public static int x, y, d ;
public static void main(String[] args) {
TimerTask clikMouse = new ClickMouse();
Timer t = new Timer();
/*
x = Integer.parseInt(args[0]) ;
y = Integer.parseInt(args[1]) ;
d = Integer.parseInt(ares[2]) ;
*/
x = 500;
y = 200;
d = 5;
t.schedule(clikMouse,1000,d*1000);
}
public void run() {
try
{
Robot bot = new Robot();
bot.mouseMove(x,y);
bot.mousePress(java.awt.event.InputEvent.BUTTON1_MASK );
bot.mouseRelease(java.awt.event.InputEvent.BUTTON1_MASK);
}
catch (Exception e)
{
System.out.println("Exception occured :" + e.getMessage());
}
}
}
https://github.com/kwhat/jnativehook JNativeHook: Global keyboard and mouse listeners for Java.
I don't have enough rep yet to leave comments, but here are my comments on the other techniques:
Use a native lib: will work, but has obvious distribution limitations
Use GlassPane to fill entire screen: GlassPanes must be contained within a Window.
Create a Window containing a picture of the desktop and fill the entire screen: Will work, but it will suddenly make the desktop static. The cursor will no longer change, any animations or video in other windows or desktop will become eerily static.
Alternative solution:
A refinement of the screen filling window, if you are using Java 6u10 or later is to make the window completely transparent. Put this window in front of all others and listen for mouse clicks. It still has shortcomings, such as no cursor changes, but it depends on what you want to do.
Based on SyntaxT3rr0r's answer I created a sample color picker in groovy which shows how it can work.
import java.awt.*
import java.awt.datatransfer.*
//import com.sun.awt.AWTUtilities;
import javax.swing.WindowConstants as WC;
import javax.swing.SwingConstants as SWC
import groovy.swing.SwingBuilder
class ColorPicker {
SwingBuilder swb = new SwingBuilder()
def window;
def overlayWindow
def mainPanel;
def mainLabel;
def menu;
def transparent = new Color(0, 0, 0, 0);
def nearlyTransparent = new Color(0, 0, 0, 26);
Color color = new Color(150, 150, 255);
def colorHex = { col ->
col = col?: color;
"#"+Integer.toHexString(col.getRGB())[2..-1]
}
def getTextColor = { baseColor ->
baseColor = baseColor?: color;
(baseColor.red*1.5 + baseColor.green*1.5 + baseColor.blue > 400) ? Color.BLACK : Color.WHITE;
}
def setDisplayColor = {newColor ->
mainPanel.background = newColor
mainLabel.foreground = getTextColor(newColor)
mainLabel.text = colorHex(newColor)
}
def show(){
menu = swb.popupMenu { // invoker: mainPanel
menuItem(text: "Pick Color", actionPerformed: capturePixelColor)
menuItem(text: "Copy to Clipboard", actionPerformed: {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(new StringSelection(colorHex()), null);
})
separator()
menuItem(text: "Close", actionPerformed: {dispose()})
}
window = swb.frame(
title: "Color Picker",
location:[50,50],
size:[60, 60],
resizable: false,
undecorated: true,
alwaysOnTop: true,
defaultCloseOperation:WC.EXIT_ON_CLOSE
){
def textColor = getTextColor()
mainPanel = panel( constraints: BorderLayout.CENTER,
border: lineBorder(color: Color.BLACK),
componentPopupMenu: menu){
borderLayout()
mainLabel = label(text: "--",
constraints: BorderLayout.CENTER,
horizontalAlignment: SWC.CENTER)
}
}
setDisplayColor(color);
window.show();
}
def capturePixelColor = {
def screenSize = Toolkit.getDefaultToolkit().screenSize
overlayWindow = swb.frame(
location:[0,0],
size: screenSize,
resizable: false,
undecorated: true,
alwaysOnTop: true,
defaultCloseOperation:WC.DISPOSE_ON_CLOSE,
show: true,
background: nearlyTransparent, // AWTUtilities.setWindowOpacity(overlayWindow, 0.1f);
cursor: Cursor.CROSSHAIR_CURSOR,
mouseClicked: {event ->
int x = event.getXOnScreen() // or maybe getX() is enough
int y = event.getYOnScreen()
overlayWindow.dispose()
overlayWindow = null
color = new Robot().getPixelColor(x, y)
setDisplayColor(color)
}
)
}
public static void main(String...args){
println "Welcome to ColorPicker"
def picker = new ColorPicker()
picker.show()
}
}
Look, I understand I am 7 years late...
This is a re-make of Keilly's answer, which allows to get when the mouse button is clicked, anywhere. The main problem is that fullscreen games are always unfocused, and it becomes annoying to handle.
Here is the code:
import java.awt.AWTEvent;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import javax.swing.JFrame;
public class Main {
public static JFrame frame = new JFrame();
public static void main(String[] args) {
Toolkit.getDefaultToolkit().addAWTEventListener(
new Listener(), AWTEvent.MOUSE_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setAlwaysOnTop(true);
frame.setLocation(1, 1);
}
private static class Listener implements AWTEventListener {
public void eventDispatched(AWTEvent event) {
// We do not want the event to show twice,
// as it shows for focusing and unfocusing
if(event.getID() == 1004) {
Point p = MouseInfo.getPointerInfo().getLocation();
System.out.println("Mouse Clicked at " + p.x + ", " + p.y);
}
// The frame was just unfocused! To make
// sure we get the next mouse click, we
// need to focus it again!
frame.setVisible(true);
}
}
}