To simply the question here, for the following code, after mouse clicking, instead of executing the code one line by another, the following happens:
1. program paused for 1 second;
2. GLabel "CLICKED" and GLabel "PAUSE FINISHED" are added to canvas at the same time after the pause.
Could someone explain this for me? Thank you very much.
public void mouseClicked(MouseEvent e){
add(new GLabel("CLICKED"),200,200);
pause(1000);
add(new GLabel("PAUSE FINISHED"),200,300);
}
While this code would work as expected:
public void run(){
add(new GLabel("CLICKED"),20,20);
pause(1000);
add(new GLabel("PAUSE FINISHED"),20,50);
}
Try using handler to run the pause on next frame: like this
public void mouseClicked(MouseEvent e){
add(new GLabel("CLICKED"), 200, 200);
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
pause(1000);
add(new GLabel("PAUSE FINISHED"), 200, 300);
}
}, 1);
}
Finally this solved my problem (Thanks #Charles Goodwin for his answer to the question: Java MouseEvent, check if pressed down)
public void mouseClicked(MouseEvent e) {
x=e.getX();
y=e.getY();
if(getElementAt(x,y)==null) return;
currentTower = (GCompound) getElementAt(x,y);
initThread();
}
private void initThread() {
new Thread() {
public void run() {
((SignalTower) currentTower).lightTower();
}
}.start();
}
public void lightTower(){
beacon.setFillColor(Color.red);
beacon.setFilled(true);
pause(500);
beacon.setFilled(false);
if(this.next!=null) this.next.lightTower();
}
Related
I want to move two objects at the same time.
I want to use Thread for this. But it gives an error in the run method.
How can I do this?
How can I do this using keyboard events
Like 2-player games?
Here's the code:
public class First extends JPanel implements Runnable,KeyListener{
int y1=303/2;
private int vy=0;
public void paintComponent(Graphics g){
g.setColor(Color.BLUE);
g.fillRect(10,y1, 15, 20);
}
public void setVelocity(int v){
vy=v;
}
#Override
public void run() {
int keyCode=e.getKeyCode();
if(keyCode==KeyEvent.VK_UP ){
}
if(keyCode==KeyEvent.VK_S){
}
else if(keyCode==KeyEvent.VK_DOWN){
}
else if(keyCode==KeyEvent.VK_W){
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args){
JFrame jf=new JFrame();
Panel p=new Panel();
jf.add(p);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(300,300);
jf.setVisible(true);
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
}
class Second extends JPanel{
int y2=303/2;
private int vy=0;
public void setVelocity(int v){
vy=v;
}
#Override
public void paintComponent(Graphics g){
g.setColor(Color.YELLOW);
g.fillRect(150,y2, 15, 20);
}
}
class Panel extends JPanel{
First f=new First ();
Second s=new Second();
public void paintComponent(Graphics g){
s.paintComponent(g);
f.paintComponent(g);
}
}
How can I do this using keyboard events Like 2-player games?
An event is only generated for the last key pressed, so basically you need to track all the keys pressed (and when they are released).
I've done this in the past using Key Bindings with a Swing Timer.
Check out the KeyboardAnimation example found in Motion Using the Keyboard for a working example of this approach.
The link will also explain what Key Bindings are and why they should be preferred over a KeyListener.
I have a JButton that will not allow me to perform the same action on any subsequent click on it after the first in the same Swing GUI instance.
JButton Run = new JButton("Run");
Run.setLocation(290, 70);
Run.setSize(120, 30);
buttonPanel.add(Run);
Run.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (Run.isEnabled()) {
errorLabel.setText("");
Result result = JUnitCore.runClasses(Run.class);
errorMessageDisplay(result);
}
}
});
totalGUI.setOpaque(true);
return totalGUI;
}
So far I thought about and tried removing the JPanel and painting all of the buttons back on, and disabling/renabling buttons.
The errorMessageDisplay method is as follows:
public void errorMessageDisplay(Result resultPass) {
if (resultPass.getFailureCount() > 0) {
errorLabel.setForeground(Color.red);
errorLabel.setVisible(true);
errorLabel.setText(" Failed");
}
else {
errorLabel.setForeground(Color.green);
errorLabel.setText(" Passed");
errorLabel.setVisible(true);
}
}
At first glance, the JUnitCore.runClasses(Run.class); call is suspicous. Also, it would be good to know what does the errorMessageDisplay() do. I believe, the problem is with one of these methods.
You can verify this with the following experimental code. Just be careful not to push it into production.
JButton run = new JButton("Run");
run.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (Run.isEnabled()) {
errorLabel.setText("");
System.out.println("Run action peformed.");
}
}
Update Since the errorMessageDisplay() looks okay, it's probably a Threading problem with JUniCore. Thus I'd try the following code:
final ExecutorService executor = Executors.newFixedThreadPool(5); // this runs stuff in background
JButton run = new JButton("Run");
// ..
run.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (Run.isEnabled()) {
executor.execute(new Runnable() { // This is how we run stuff in background. You can use lambdas instead of Runnables.
public void run() {
final Result result = JUnitCore.runClasses(Run.class); // Run.class is different from the current JButton run.
SwingUtilities.invokeLater(new Runnable() { // Now we go back to the GUI thread
public void run() {
errorMessageDisplay(result);
}
});
}
});
}
});
I'm making a game where the players are taking turns and they would have a set of buttons each that they can click when it is their turn. Below is a sample code that follows the logic of what I am saying. But what happens is when I clicked the "btn1", it prints three 1s and I can still click the second button.
//this loop is in the main
for(int i=0; i<3;i++){
if(player==1){
player1();
}
else if (player==2){
player2();
}
}
public void player1(){
btn1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
System.out.println("\n1");
player=2;
}});
}
public void player2(){
btn2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
System.out.println("\n2");
player=1;
}});
}
I can see what could be the problem but I don't know what to do.
Replace the loop
for(int i=0; i<3;i++){
if(player==1){
player1();
}
else if (player==2){
player2();
}
}
with just
player1();
player2();
Instead of adding 3 times the same listener to the button add it just once
If all you want to do is enable and disable buttons, why not do:
public void player1(){
btn1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
System.out.println("\n1");
player=2;
btn1.setEnabled(false);
btn2.setEnabled(true);
}});
}
public void player2(){
btn2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
System.out.println("\n2");
player=1;
btn1.setEnabled(true);
btn2.setEnabled(false);
}});
}
This is just the begining of the game, where there are two squares, one can be controlled by arrow keys and other by mouse, they can fire balls on each other and simultaneously can be saved, the one getting maximum hits will win...
In this code when I fire from the second square there is a long line which goes towards the second player and whole of the game has to halt..
package raship;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.IOException;
public class raship extends Applet implements KeyListener, MouseMotionListener, MouseListener, Runnable
{
int width,flag1=0,flag2=0,height,x1,y1,x2,y2,calc1,calc2x,calc2y;
Thread t=null;
public void init()
{
//Toolkit toolkit=Toolkit.getDefaultToolkit();
t=new Thread();
width=getSize().width;
height=getSize().height;
x1=0;y1=height/2;
x2=width-10;y2=height/2;
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
setBackground(Color.gray);
repaint();
}
public void keyPressed(KeyEvent e)
{
int c=e.getKeyCode();
System.out.println(c);
if(c==KeyEvent.VK_LEFT)
{
System.out.println("yeah it's on");
x1-=10;
}
else if(c==KeyEvent.VK_UP)
y1-=10;
else if(c==KeyEvent.VK_RIGHT)
x1+=10;
else if(c==KeyEvent.VK_DOWN)
y1+=10;
if(x1>=0 && y1>=0 && y1<=height-20 && x1<=3*width/4)
repaint();
}
public void keyReleased(KeyEvent arg0) {
}
public void keyTyped(KeyEvent arg0) {
}
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e)
{
x2=e.getX();
y2=e.getY();
if(x2>=5*width/8 && x2<=width-20)
repaint();
}
public void mouseClicked(MouseEvent e)
{
flag2=1;
calc2x=x2;
calc2y=y2;
System.out.println(calc2x);
}
public void mouseEntered(MouseEvent arg0) {
}
public void mouseExited(MouseEvent arg0) {
}
public void mousePressed(MouseEvent arg0) {
}
public void mouseReleased(MouseEvent arg0) {
}
public void paint(Graphics g)
{
width=getSize().width;
height=getSize().height;
g.setColor(Color.green);
g.fillRect(x1, y1, 20, 20);
g.setColor(Color.red);
g.fillRect(x2, y2, 20, 20);
if(flag2==1)
{
g.setColor(Color.yellow);
while(true)
{
calc2x-=1;
System.out.println(calc2x);
g.fillOval(calc2x,calc2y,10,10);
try {
Thread.sleep(4);
} catch (InterruptedException e) {e.printStackTrace();}
if(calc2x<10)
{
flag2=0;
break;
}
}
}
}
#SuppressWarnings("static-access")
public void run()
{
if(flag2==1)
while(true)
{
{
repaint();
System.out.println("calc2x="+calc2x);
if(calc2x<10)
{
flag2=0;
}
try
{
t.sleep(4);
} catch (InterruptedException e) {e.printStackTrace();}
calc2x-=1;
}
}
}
}
NEVER have Thread.sleep(...) in a paint method. EVER. This puts all your drawing to sleep. In fact simply calling Thread.sleep(...) in your GUI thread will be enough to put the GUI to sleep, but its worse still in a paint method, since that method must be called over and over, and needs to be blazing fast and over in the blink of an eye or less.
Instead:
Create a Swing JApplet, not an AWT Applet
Override the paintComponent method of a JPanel to do your drawing
Use a Swing Timer to do your game loop.
Edit
You state in comment:
#HovercraftFullOfEels if you can write the syntax of swing timer and swing applet it would be of great help....
You appear to be wanting me to write tutorials for you. I wish I had all the time to do that, but alas, I don't, and I feel that it would be much more efficient for both you and me for you to check out the decent tutorials with sample code that are already in existence just waiting for you to learn from. For example, please check out the following links:
The Java Tutorials, The Really Big Index
Java Applets
Using Swing Components
How to make Java Applets
How to Use Swing Timers
I don't want to create anymore JLabel object. I want to use addMouseListener because this way too pratice. But If I use this mouse listener doesn't work. Why?
Working code:
JLabel lb = new JLabel("Label 1");
lb.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if(e.isShiftDown()){
System.out.println("Click");
}
}
});
Doesn't work:
add(new JLabel("Label1").addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if(e.isShiftDown()){
System.out.println("Click triggered");
}
}
}));
addMouseListener(...)
Returns void therefore you cannot use the result as an argument for an other method call.