I want to make code that When I pressed left upper area, the rectangle chosen and resize it using drag and drop (right down is fixed and use left up point to resize).
class MyMouseListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
start = e.getPoint();
if((up.a<start.x&&start.x<up.a+10&&up.b<start.y&&start.y<up.b+10)) {//When I pressed Rectangle's left up area
Label.setText("up");
if(tempshape==null) {
tempshape=shapes.get(now);
}
ud=1;
}
tempshape is a global variable and I want to get only first data so
I claimed tempshape as:
shape tempshape=null;
if(ud==1) {
else if(nowshape=="Rectangle") {
shapes.get(now).setA(end.x);
shapes.get(now).setB(end.y);
shapes.get(now).setC(tempshape.c+end.x);
shapes.get(now).setD(tempshape.d+end.y);
}
} ]
But tempshape is still update it's value while I dragging so I get trash data from tempshape.
I want to know:
Why tempshape is updating while dragging? (I only Write tempshape's update code in pressed.)
How can I solve this problem?
Related
I am learning Java with the program named Processing.
However, I cannot understand why my code do not work appropriately.
I made a arm with this problem which should be rotated to upside or downside when I hold the mouse button, but it just works when I hold the left button on my mouse, and it does not work when I hold the right button.
The problem is I do not know the problem of my code as follows.
float angle=0;
float angleDirection=1;
float speed=0.005;
void setup(){
size(800,600);
}
void draw(){
background(255,255,255);
stroke(20,20,255);
translate(400,300);
rotate(angle);
strokeWeight(18);
line(0,0,140,0);
pushMatrix();
translate(140,0);
rotate(angle*2.0);
strokeWeight(14);
line(0,0,100,0);
translate(100,0);
rotate(angle*2.5);
strokeWeight(10);
line(0,0,60,0);
popMatrix();
rotate(-angle*2.0);
strokeWeight(18);
line(0,0,-140,0);
translate(-140,0);
rotate(-angle*2.0);
strokeWeight(14);
line(0,0,-100,0);
translate(-100,0);
rotate(-angle*2.5);
strokeWeight(10);
line(0,0,-60,0);
if(mousePressed){
if(mouseButton==LEFT){
angle=angle+speed*angleDirection;
if((angle>QUARTER_PI)||(angle<0)){
angle=QUARTER_PI;
}
if(mouseButton==RIGHT){
angle=angle+speed*angleDirection;
if((angle>QUARTER_PI)||(angle<0)){
angleDirection=-angleDirection;
angle=QUARTER_PI;
}
}
}
}
}
You're almost there, but accidentally made a logical error: the right button condition is nested inside the left button condition. Since the mouseButton can only be either left or right (but not both), the right button condition will never trigger. Simply move it outside of the left button condition:
if (mousePressed) {
if (mouseButton==LEFT) {
angle=angle+speed*angleDirection;
if ((angle>QUARTER_PI)||(angle<0)) {
angle=QUARTER_PI;
}
}
if (mouseButton==RIGHT) {
angle=angle+speed*angleDirection;
if ((angle>QUARTER_PI)||(angle<0)) {
angleDirection=-angleDirection;
angle=QUARTER_PI;
}
}
}
(Edit > Auto Format (Ctrl+T / CMD + T) will make it easier to spot {} issues)
Have fun learning!
I have mouseMotionListener in my jpanel code.
But how can I know if the mouse dragged to left or right inside the jpanel?
Use
if (currentX > previousX) {
// Right
} else {
// Left
}
previousX = currentX;
in your listener.
Hope this helps.
In the event callback: store the mouse-(x-)position, in the next callback calculate the difference to the previous position (and store the position again); depending on the sign(um) you can determine whether it was a left or right drag.
This is my code:
JTable1.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1)
{
JTable target = (JTable)e.getSource();
Point pMouse = new Point();
pMouse = target.getMousePosition();
}
}
}
So I am retrieving the point (coordinates) relative to the JTable. So let's say the user clicks somewhere in a cell and the returned Point is X=272 and Y=50. So now I want to position a JDialog exactly by those coordinates. I tried:
jDialog1.setLocation(pMouse);
jDialog1.setVisible(true);
But this positions the Dialog somewhere else (the coordinates of the screen instead of the Table). Does somebody have a suggestion on how I can position the JDialog relative to the cell?
You are using the co-ordinates in relation to the client area of the JTable content. You want the global co-ordinates in relation to the entire window. For this you can use:
Point location = MouseInfo.getPointerInfo().getLocation();
jDialog1.setLocation(location);
In general, a user should be able to use your application either by mouse or keyboard. What happens if the user tabs to that cell? Should they not be able to see the same dialog? So for a more general solution that works whether you use a mouse or not:
SwingUtilities.convertPointToScreen(point, table);
Check out the other convertXXX methods in SwingUtilities for future reference.
Or, you can always use:
Component.getLocationOnScreen();
and then add on the mouse point.
I have a question regarding the callback speed of the mouseDragged message of the MouseMotionListener in Java Swing. This post is sort of related but it's not entirely the same so I started a question of my own.
I'm making a small in-house application with no eye on commercial distribution that is basically a digitalized TCG (Trading Card Game) emulator. For any of you familiar with MtG (Magic the Gathering), you might've heard from such a similar program. I'm trying to create something that looks sort of like this, but less fancy.
My GUI consists of a JFrame with menu and then some panels containing various buttons and labels, but I'll only go over the relevent parts to explain my problem.
In essence, I'm using a vertical split JSplitPane with a JPanel on the left, with in that a JScrollPane with a JList in it, which represents at any time the cards in your hand that you can play. On the right side of the split, I have a JLayeredPane with a background image in the DEFAULT_LAYER (subclass of JPanel that overrides the draw function to add an image) and, on various layers above the PALETTE_LAYER, I display the cards that are in play (gathered in an ArrayList) by means of custom CardPanels (another subclass of JPanel that illustrates a card). The entire JLayeredPane is thus a representation of the table in front of you with all the cards you've already played.
I first started by adding a MouseListener and a MouseMotionListener to the JLayeredPane to pick up events, allowing me to register a mouse press, check if this was above a card, then use the mouse dragged event to move the card around and finally mouse release to place it back . This all works perfectly fine and if I add logging information I can see the mouseDragged callback function is called often, allowing for a visually fast dragging motion without lag.
Today I decided to add functionality to allow the user to drag a card from his hand to the "table" (instead of double clicking on the card in the JList), so I added the appropriate listeners to the JList along with filling in some functions like MousePressed and MouseReleased. On a mouse press, I check what card from the list was clicked, I lock the list, create a custom CardPanel (but don't add it anywhere yet, I just allocate and initiate it!) and set a flag. In mouse dragged, I check if this flag is set. If it is, I check where the cursor is. If it is anywhere above the JLayeredPane, I add the CardPanel to the DRAG_LAYER and set another flag. If this second flag is set in successive calls to mouse dragged, I don't add the panel again but I just change the location. This functionality is practically the same as the one in my previous mouse dragged callback. On mouse release, I unlock the list and add the CardPanel on the correct layer in the JLayeredPane.
Everything is working as intended so I'm pretty sure my code is okay, but there is just one slight issue:
When dragging a card from the list to the layered pane (instead of from the layered pane to the layered pane), I notice the mouseDragged callback is called at a pretty low frequency by the JList (approx 10 times per second), introducing some visually disturbing lag (compared to approx 30 times per second in the first case of dragging).
I'm going to add some code snippets as to clarify my problem but I'm afraid adding all the code to allow you to run it yourself would be serious overkill.
The main question in this post is: does anybody know why the mouseDragged is called faster by one MouseMotionListener than by another MouseMotionListener? The listener to the JLayeredPane component makes fast successive calls, the listener to the JList calls significantly slower.
Note: I'm developing in Netbeans and I'm using the built-in graphical Swing Interface Builder. I'm using a JFrame form as my main class.
public class MyFrame extends JFrame{
...
protected JLayeredPane layeredPane;
protected JList cardsInHandList;
...
...
protected ArrayList<String> cardsInHand;
...
private void attachListeners(){
layeredPane.addMouseListener(new MouseAdapter(){
public void MousePressed(MouseEvent e){
// set a flag, start a drag
}
public void MouseReleased(MouseEvent e){
// unset a flag, stop a drag
}
});
layeredPane.addMouseMotionListener(new MouseMotionAdapter(){
public void MouseDragged(MouseEvent e){
// drag the card around
// gets called a lot!
// actual code:
if (e.getButton() == MouseEvent.BUTTON1) {
if (!dragging) return; // the flag
int x = e.getX() - 10;
int y = e.getY() - 10;
// snap to grid
x /= GRIDX;
x *= GRIDX;
y /= GRIDY;
y *= GRIDY;
// redraw the card at its new location
draggedCard.setLocation(x, y);
}
}
});
cardsInHandList.addMouseListener(new MouseAdapter(){
public void MousePressed(MouseEvent e){
// set a flag, start a drag
}
public void MouseReleased(MouseEvent e){
// unset a flag, stop a drag
}
});
cardsInHandList.addMouseMotionListener(new MouseMotionAdapter(){
public void MouseDragged(MouseEvent evt){
// check cursor location, drag if within bounds of layeredPane
// gets called a whole lot less!! _Why?_
// actual code:
if (!draggingFromHand) return; // the flag
// check location of cursor with own method (contains() didn't work for me)
if (isCursorAtPointAboveLayeredPane(evt.getLocationOnScreen())) {
// calculate where and snap to grid
int x = (int) (evt.getLocationOnScreen().getX() - layeredPane.getLocationOnScreen().getX())-10;
int y = (int) (evt.getLocationOnScreen().getY() - layeredPane.getLocationOnScreen().getY())-10;
// snap to grid
x /= GRIDX;
x *= GRIDX;
y /= GRIDY;
y *= GRIDY;
if(!draggingFromHandCardPanelAdded){
layeredPane.add(draggingFromHandCardPanel, JLayeredPane.DRAG_LAYER);
draggingFromHandCardPanelAdded = true;
} else {
draggingFromHandCardPanel.setLocation(x,y);
}
}
}
});
}
I'll try to build a short runnable example reproducing the problem and then attach the code somewhere but right now I got to skoot.
Thanks in advance
PS: I am aware that there is another way to drag in Java, involving TransferHandlers and all that but it just seems like too much hassle and it isn't an actual answer to my question of how come the one callback seems to be called more than the other, so please don't tell me to use that instead.
Once you drag outside the list, Java start generating synthetic mouse events for the list, which might be the cause. See the javadoc for JComponent#setAutoscrolls(boolean).
You might get better results using a global event listener, see
http://tips4java.wordpress.com/2009/08/30/global-event-listeners/
Is there a way to make the mouseDragged Event be called more Often ( In my Case, Drawing a Color? I need it for Smooth Drawing, because right now, if you move too fast, it doesn't Draw All my Path. Also, I have an 2D Array Storing the Color of the Pixel, so that's also Problematic if I try to solve by problem by another Way, that's why I thought Increasing the mouseDragged Frequency would be the Best thing to Do
Thanks
If you want smooth drawing, you'd likely have to interpolate the data yourself. If you get an event at (3,3) and another at (10,10) you can figure the slope between the two, and iterate through the logical points that the mouse must have been dragged to get from (3,3) to (10,10)
I don't know of a way to force mouseDragged to update faster, and if, for instance the system was under high load, or someone used a touch screen, you might get huge jumps anyhow.
If you are drawing ovals to as color lines, change to lines:
ArrayList<> colors;
mousepressed(Event e) {
startPoint = e.getPoint();
}
mousedragged(Event e) {
colors.add(new Color(startPoint, e.getPoint);
startPoint = e.getPoint();
}
class Color() {
Color(Point start, Point end) {
// ...
}
paint(Graphics g) {
g.drawLine(start, end);
}
}