using a jpanel in another class? (noob issue) - java

I have the classes:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class MyTimer extends JFrame {
static JButton quitButton;
static JButton quit_2Button;
public MyTimer() {
initUI();
}
public static void random(){
int x = (int)(Math.random() * 100 + 1);
int y = (int)(Math.random() * 150 + 1);
System.out.println(x);
System.out.println(y);
quitButton = new JButton("Press this to quit?");
quitButton.setBounds(x, y, 200, 20);
}
public void initUI() {
random();
JPanel panel = new JPanel();
getContentPane().add(panel);
panel.setLayout(null);
JButton quit_2Button = new JButton("Or maybe press this to quit!");
quit_2Button.setBounds(50, 100, 200, 20);
quit_2Button.setRolloverEnabled(true);
quit_2Button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
quitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
finder.main(null);
}
});
panel.add(quitButton);
panel.add(quit_2Button);
setTitle("Java");
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
, and
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class timer_run {
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e) {
panel.remove(); //error here
}
};
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MyTimer ex = new MyTimer();
ex.setVisible(true);
new timer_run();
}
});
}
public timer_run() {
Timer timer = new Timer(1000, al);
timer.start();
}
}
and I am trying to make it so that when actionlistener al is activated, jpanel.remove(quit_2Button) is called. The problem is, that whenever i try and do this it gives me the error "panel cannot be resolved". I assume the reason this is happening is because timer_run does not have access to the JPanel frame, but through various trial and error have not been able to fix this. Does anybody have any suggstions about what I could possibly do to let timer_run see the JPanel frame? thanks in advance, and please note I am a java noob, so make the answer as simple as you can, if possible?

Recommendations:
One class should not try to directly manipulate variables of another class.
Instead have one class call public methods of the other class.
To allow your second class to do that, you need to pass a reference of the first class's object into that of the second class. I suggest you do this via a constructor parameter.
For example
// class name should begin with an upper case letter
public class TimerRun {
private MyTimer myTimer;
public TimerRun(MyTimer myTimer) {
this.myTimer = myTimer;
}
//....
}
Now the TimerRun class can call public methods on the MyTimer object held by myTimer by calling, myTimer.someMethod()

Related

How to add funtionallity to a Jbutton,located in superclass from a subclass?

I am trying to add functionality to a Jbutton using subclass butt Jbutton is actually declared and defined in super class.
Here is my code:
JButton zz=new JButton(ss);
zz.setBounds(470,70,35,35);
zz.setBorder(oo);
zz.setBackground(new Color(0,170,120));
l.add(zz);
This is my Jbutton located in super class named as realestate in my project.I have created subclass in which i am trying to add action listener for this button.
Here is my subclass:
public class assan extends RealEstate{
zz.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent u)
{
System.out.println("kk");
}
});}
butt i run this program i got different types of errors such as:
Package 'zz' does not exist etc.
This is my full code:
package realestate;
import java.awt.Color;
import javax.swing.*;
public class Realestate extends JFrame {
Realestate()
{
JLabel l=new JLabel(new ImageIcon("C:\\Users\\MUHAMMAD SHAHAB\\Documents\\NetBeansProjects\\Real Estate\\src\\real\\estate\\file (2).jpg"));
l.setBounds(100,50,300,250);
add(l);
ImageIcon ss=new ImageIcon("C:\\Users\\MUHAMMAD SHAHAB\\Documents\\NetBeansProjects\\Real Estate\\src\\real\\estate\\1470672145_Help_mark_query_question_support_talk.png");
public JButton zz=new JButton(ss);
zz.setBounds(470,70,35,35);
zz.setBackground(new Color(0,170,120));
l.add(zz);
}
public class assan extends Realestate{
zz.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent o)
{
System.out.println("Cena");
}
});
}
public static void main(String[] args) {
RealEstate v=new RealEstate();
v.setUndecorated(true);
v.setVisible(true);
v.setBounds(350,200,600,350);
v.setForeground(Color.WHITE);
assan n=new assan();
}
}
what am i doing wrong?
Imagine that this is the superclass:
public class RealEstate{
public JButton button = new JButton("Button Name");
}
And this the subclass:
public class SubClass extends RealEstate{
/**
* Constructor
*/
public SubClass(){
//The Button is public so it is visible to the subclass
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent u){
System.out.println("Hello World!");
}
});
}
}
Also have a look at this (tutorial)
A minimal example of the code you may need:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.Border;
public class RealEstate extends JFrame {
public JButton button = new JButton("Button");
/**
* Constructor
*/
public RealEstate() {
//Button
button.setText("I am a JButton");
// ...rest of the code below
}
/**
* The SubClass
*/
protected class SubClass extends RealEstate {
/**
* Constructor
*/
public SubClass() {
//accessing the button from the SubClass
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent u) {
System.out.println("Hello World!");
}
});
}
}
/**
* Main Method
*
* #param args
*/
public static void main(String[] args) {
RealEstate v = new RealEstate();
v.setUndecorated(true);
v.setVisible(true);
v.setSize(600,600);
v.setForeground(Color.WHITE);
v.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Put the following class in the file RealState.java:
public class RealEstate extends JFrame {
protected JButton zz = null;
RealEstate() {
JLabel l = new JLabel("Label");
l.setBounds(100, 50, 300, 250);
add(l);
// ImageIcon ss = new ImageIcon("path_to_image_file");
zz = new JButton("MyButton");
zz.setBounds(470, 70, 35, 35);
zz.setBackground(new Color(0, 170, 120));
add(zz);
}
}
And put the subclass in its own file too: Assan.java
public class Assan extends RealEstate {
public Assan() {
zz.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent o) {
System.out.println("Cena");
}
});
}
public static void main(String[] args) {
Assan v = new Assan();
v.setUndecorated(true);
v.setVisible(true);
v.setBounds(350, 200, 600, 350);
v.setForeground(Color.WHITE);
}
}
Note that I have made two changes:
make the variable you want to modify in the subclass protected
move the main method to the subclass if you want the event handler to be executed.
And lastly, you have to follow some tutorials, for example
Here you will learn about inheritance
Java Swing tutorials.
Please see the following and read the comments carefully. The code is meant not only to highlight some errors, but also demonstrate the idea of MCVE :
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
//Java is case sensetive. You can't call a class Realestate
//and later use RealEstate v= new RealEstate();
public class RealEstate /*Realestate*/ extends JFrame {
//to make zz visible to other classes it should be a field
public JButton zz;
RealEstate()
{
//remove what is not needed to demonstrate the problem, remove it
//JLabel l
//ImageIcon ss=new ImageIcon("C:\\Users\\MUHAMMAD SHAHAB\\Documents\\NetBeansProjects\\Real Estate\\src\\real\\estate\\1470672145_Help_mark_query_question_support_talk.png");
//wrong
//public JButton zz=new JButton("Button");
zz=new JButton("Button");
zz.setBounds(470,70,35,35);
zz.setBackground(new Color(0,170,120));
add(zz);
//you can't add a button to a JLabel
//l.add(zz);
}
public static void main(String[] args) {
RealEstate v= new RealEstate();
v.setUndecorated(true);
v.setVisible(true);
v.setBounds(350,200,600,350);
v.setForeground(Color.WHITE);
Assan n= new Assan();
}
}
//Use right naming convention. Assan and not assan
class Assan extends RealEstate{
//this code has to be enclosed in a constructor
//or a method
//zz.addActionListener(new ActionListener(){
// public void actionPerformed(ActionEvent o)
// {
// System.out.println("Cena");
// }
//});
Assan(){
zz.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent o)
{
System.out.println("Cena");
}
});
}
}

JProgressBar instantiate it self multiple time

I'm trying to add a JProgressBar to a simple program just to learn. So far i can display it, but it adds multiple instance while i want just one to show.
Here's the code :
package package1;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
public class Opening extends JPanel {
private JProgressBar loadingBar;
private Thread t;
public void paintComponent(Graphics g)
{
super.paintComponent(g);
//Loading bar
bar();
}
private void bar()
{
loadingBar = new JProgressBar();
t = new Thread(new LoadMyBar());
this.add(loadingBar).setLocation(25, 600);
loadingBar.setSize(625, 25);
loadingBar.setStringPainted(true);
loadingBar.setValue(0);
loadingBar.setMinimum(0);
loadingBar.setMaximum(100);
t.start();
}
class LoadMyBar implements Runnable
{
public void run(){
for(int i = loadingBar.getMinimum(); i <= loadingBar.getMaximum(); i++)
{
loadingBar.setValue(i);
try
{
t.sleep(1000);
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
Any idea on what i'm doing wrong?
You're calling bar() inside of the paintComponent(Graphics g) method. This method is responsible for drawing the component and can be called potentially many times and not in your control. Don't do that, but rather call it once in a constructor or some other location where it can be called just once.
You're also setting the JProgressBar's value off of the Swing event thread, something that can be dangerous to do. Use a Swing Timer instead or use a SwingWorker's progress property together with a PropertyChangeListener.
e.g.,
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
#SuppressWarnings("serial")
public class Opening extends JPanel {
private static final int TIMER_DELAY = 1000;
private JProgressBar loadingBar;
private Timer t = new Timer(TIMER_DELAY, new TimerListener());
public Opening() {
bar();
}
private void bar() {
loadingBar = new JProgressBar();
this.add(loadingBar);
loadingBar.setStringPainted(true);
loadingBar.setValue(0);
loadingBar.setMinimum(0);
loadingBar.setMaximum(100);
t.start();
}
private class TimerListener implements ActionListener {
int value = 0;
#Override
public void actionPerformed(ActionEvent e) {
if (value <= 100) {
loadingBar.setValue(value);
value++;
} else {
// value > 100
((Timer) e.getSource()).stop(); // stop timer
}
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Opening");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(new Opening());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
You are creating the JProgressBar and adding it to your class Opening in the method paintComponent().
paintComponent() is called every time, the component needs to draw itself.
This can be after resizing the window (JFrame) or some other application overlapping your application.
You should move the initialization to the constructor of Opening.
See http://docs.oracle.com/javase/tutorial/uiswing/painting/closer.html

Using SwingWorker to update the progress of a thread from another class

Value is updated by the end, but not during the process. I guess the reason is that the publish method locates outside the loop.
As to invoke PropertyChangeListener, can it be achieved by defining the class without extends SwingWorker<Void, Void> ?
To address the question in another way, I have two threads locate in two different classes. Is it possible to build communication between the two using SwingWorker?
Class Application
import javax.swing.JFrame;
public class Application {
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
JFrame frame = new Progress();
frame.setSize(200, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
Class Progress
import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
#SuppressWarnings("serial")
public class Progress extends JFrame{
private JProgressBar progressbar;
public Progress(){
JButton button = new JButton("Run");
progressbar = new JProgressBar(0, 100);
progressbar.setValue(0);
progressbar.setStringPainted(true);
JPanel panel = new JPanel();
panel.add(button);
panel.add(progressbar);
add(panel, BorderLayout.PAGE_START);
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
start();
}
});
}
private void start(){
progressbar.setValue(0);
SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>(){
#Override
protected Void doInBackground() throws Exception {
Simulation sim = new Simulation();
publish(sim.getCount());
return null;
}
#Override
protected void process(List<Integer> chunks) {
Integer progress = chunks.get(chunks.size()-1);
progressbar.setValue(progress);
progressbar.repaint();
progressbar.update(progressbar.getGraphics());
}
#Override
protected void done() {
Toolkit.getDefaultToolkit().beep();
}
};
worker.execute();
}
}
Class Simulation
public class Simulation {
private int count;
public Simulation(){
for(int i=0; i<100; i++){
count++;
System.out.println(count);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public int getCount(){
return count;
}
}
How can I update the value during the process?
You need to implement PropertyChangeListener on your SwingWorker and listen to the Progress property changes and then from overridden propertChange() method update your JProgressBar.
Here is what you are looking.
Hope this helps.

Button New Game not working Java [duplicate]

This question already has answers here:
How to draw in JPanel? (Swing/graphics Java)
(4 answers)
Closed 9 years ago.
Hi im making a project for my studies and im new in java. I need to do a game - Arkanoid. What i wanted to do is a game manu with 2 buttons "New game" and "Quit". Someone from stackoverflow.com rebuild my menu code but it still doesnt work :( After clicking a "New Game" im getting blank frame :(. Probably becouse of Gra constructor. How constructor of Gra need to look like to make it works with my menu code.
Here is the code (i will paste all Arkanoid class code and most important parts of Gra class):
Arkanoid class:
package arkanoid;
import javax.swing.*;
import java.awt.event.*;
public class Arkanoid extends JFrame
{
private static final long serialVersionUID = 5647459635833443178L;
public Arkanoid() {
super("Arkanoid");
setSize(500,400);
setTitle("Arkanoid BETA");
setLocationRelativeTo(null);
setResizable(false);
final JPanel panel = new JPanel();
setContentPane(panel);
panel.add(new JButton(new AbstractAction("New game") {
public void actionPerformed (ActionEvent e) {
panel.removeAll();
panel.add(new Gra()); //constructor of Gra need to return some Panel i think but i dont know how to do that
panel.revalidate();
panel.repaint();
}
}));
panel.add(new JButton(new AbstractAction("Quit") {
public void actionPerformed (ActionEvent e) {
Arkanoid.this.setVisible(false);
}
}));
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Arkanoid frame = new Arkanoid();
frame.setVisible(true);
}
});
}
}
Gra class:
package arkanoid;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JOptionPane;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class Gra extends JPanel
{
/*some not important variables*/
Pilka pilka;
Paletka paletka;
Cegla cegla_tab[];
Serce serce_tab[];
Timer timer;
public Gra()
{
addKeyListener(new TAdapter());
setFocusable(true);
cegla_tab = new Cegla[liczba_cegiel];
serce_tab = new Serce[max_zycia];
//setDoubleBuffered(true);
timer = new Timer();
timer.scheduleAtFixedRate(new ScheduleTask(), 1000, 10);
}
public void addNotify()
{
super.addNotify();
start_gry();
}
public void start_gry()
{
pilka = new Pilka();
paletka = new Paletka();
/* painting a bricks and lifes for game start */
}
public void koniec_gry() //end of a game
{
czas_konca = System.currentTimeMillis();
gra = 3;
timer.cancel();
}
public void paint(Graphics g)
{
super.paint(g);
//repaiting ball positions, bricks and paddle
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
private class TAdapter extends KeyAdapter
{
public void keyReleased(KeyEvent e)
{
paletka.klawisz_puszczony(e);
}
public void keyPressed(KeyEvent e)
{
paletka.klawisz_wcisniety(e);
}
}
class ScheduleTask extends TimerTask
{
public void run()
{
if(paletka.czy_pausa()==false)
{
pilka.przesun();
paletka.przesun();
czy_zderzenie();
repaint();
}
}
}
public void czy_zderzenie()
{
//checking a collisions with bricks
}
}
You need to override paintComponent, not paint.
Also, Gra's constructor does return a JPanel. The constructor will return the object you're constructing, which in this case is a Gra, which is also a JPanel. This is polymorphism at work.
Oh, and as per the comment above, you really shouldn't be disposing of the graphics object.

JLabel mouse click on icon or text

When it is clicked on JLabel, I want to understand if the click was on "Icon part", or "Text part" of the JLabel, so that different action can be taken. Is there a clever way to do that? Or just I have to solve it relatively with the coordinates of the icon and text?
+1 to #aymeric comment.
What about having two different JLabels
However I do understand why you might be hesitating
negative: requires maintenance of 2 labels.
My clever (:P) solution to this is create your own abstract component - which accepts icon and text as parameters for constructor - by extending JPanel and than adding 2 JLabels to the JPanel, each label has its on MouseAdapter which calls abstract method xxxClicked() (thus any implementing class must override these methods).
Here is an example I made:
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon ii = null;
try {
//I dont remmend getScaledInstance just used it for speed of code writing
ii = new ImageIcon(ImageIO.read(new URL("http://www.candonetworking.com/java.gif")).getScaledInstance(32, 32, Image.SCALE_SMOOTH));
} catch (Exception ex) {
ex.printStackTrace();
}
MyLabel ml = new MyLabel(ii, "Something") {
#Override
void iconClicked() {
System.out.println("Icon clicked");
}
#Override
void textClicked() {
System.out.println("Text clicked");
}
};
frame.add(ml);
frame.pack();
frame.setVisible(true);
}
});
}
}
abstract class MyLabel extends JPanel {
JLabel iconLabel;
JLabel textLabel;
MouseAdapter iconMA;
MouseAdapter textMA;
public MyLabel(ImageIcon icon, String text) {
iconLabel = new JLabel(icon);
textLabel = new JLabel(text);
iconMA = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent me) {
super.mouseClicked(me);
iconClicked();
}
};
textMA = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent me) {
super.mouseClicked(me);
textClicked();
}
};
iconLabel.addMouseListener(iconMA);
textLabel.addMouseListener(textMA);
add(iconLabel);
add(textLabel);
}
abstract void iconClicked();
abstract void textClicked();
public JLabel getIconLabel() {
return iconLabel;
}
public JLabel getTextLabel() {
return textLabel;
}
}

Categories

Resources