How can I make this JButton work - java

I am working on a code that will generate a random number when you press a button and output that number. I have wrote this code and it compiles but when I press the button nothing works. Can someone please help. Here is some of my code.
public class slotmachine extends JApplet {
JButton b1 = new JButton("START");
JPanel p;
int Int1;
public slotmachine() {
init();
}
public void init() {
this.setLayout(null);
this.setSize(1000, 1000);
JButton b1 = new JButton("START");
b1.setBounds(100, 100, 100, 100);
getContentPane().add(b1);
repaint();
}
public void run() {
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Random random1 = new Random();
int Int1 = random1.nextInt(11);
}
});
}
public void paint(Graphics g) {
g.drawString("Your number is" + Int1, 30, 30);
}
}

Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
You create a local variable of Int1 within the ActionListener for the button. This has no relationship to the Int1 of the class.
You never tell the UI to update
You break the paint chain by failing to call super.paint (be ready for some seriously weird and wonderful graphics glitches)
You've made the same mistake with b1 as you have with Int1. You create an instance level field, but shadow it with a local variable in init, meaning when start is called, b1 is null, which will result in a NullPointerxception
Instead, add a JLabel to your applet, use it's setText method to display the random value
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Random random1 = new Random();
int Int1 = random1.nextInt(11);
lable.setText(Integer.toString(Int1));
}
});
Also, if possible, I'd avoid using JApplet, they have their own set of issues which can make life more difficult then it needs to be when learning the Swing API. Instead, try using a JPanel for your main container and then add it to an instance of a JFrame.
Also, take a look at:
Understanding Class Members for more information about local and class/instance context for variables
How to Use Labels
Why is it frowned upon to use a null layout in SWING? and Laying Out Components Within a Container
And if your really interested in how painting works, Performing Custom Painting and Painting in AWT and Swing
for more details

Related

Why isn't a string drawn on frame?

I have tried this code to draw a string on my frame using KeyListener interface such that whenever I hit a typeable key on keyboard, it should appear on frame but it doesn't work even though there are no errors.
Can someone tell what's the mistake?
Below is my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class KeyevntFrame2 extends Frame {
Button b = new Button("ok");
Button b1 = new Button("hey");
char ch;
String s = "";
public KeyevntFrame2() {
setTitle("understand key events");
setSize(800, 600);
addKeyListener(new KeyHandler());
setFont(new Font("Arial", Font.PLAIN, 35));
setForeground(Color.BLACK);
add(b);
add(b1);
b.setBounds(200, 200, 100, 100);
b1.setBounds(200, 700, 100, 100);
setLayout(null);
b.addActionListener(new KeyHandler());
b1.addActionListener(new KeyHandler());
}
class KeyHandler implements KeyListener, ActionListener {
public void keyPressed(KeyEvent e) {
ch = e.getKeyChar();
s = s + ch;
repaint();
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public void paint(Graphics g) {
g.drawString(s, 300, 200);
g.setFont(new Font("Arial", Font.PLAIN, 35));
}
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(b1, "thank you for using java");
}
}
public static void main(String a[]) {
KeyevntFrame2 f = new KeyevntFrame2();
f.setVisible(true);
}
}
Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or combinations of them along with layout padding and borders for white space. This advice is especially relevant to this GUI, given that the frame does not have enough height to display the second button.
Don't mix AWT (Frame) and Swing (JOptionPane) components in one GUI. Choose a GUI toolkit and stick with it.
Always use #Override notation when changing the behavior of existing methods or implementing the methods of an interface. Doing so would have warned you that neither the KeyListener nor ActionListener interfaces define a public void paint(Graphics) method!
Defining a combined KeyListener and ActionListener does not make much sense, and has confused you into thinking that calling Button.addActionListener(..) with the combined listener will also have the effect of adding it as a KeyListener. It won't.
new Font("Arial", Font.PLAIN, 35) for cross-platform robustness, that should be new Font(Font.SANS_SERIF, Font.PLAIN, 35) (e.g OS X will typically not have the Arial font installed, and users would prefer to see Helvetica in any case.)
It is not necessary to set the font of the frame, and also the font in the paint method. Just do it once in the frame.
Since the frame itself is not focusable, calling addKeyListener(..) will have no effect. Better to use Swing and implement key bindings in any case.
When custom painting, always call the super method first.
Swing and AWT GUIs should be started on the EDT.
"it doesn't work even though there are no errors." There are plenty of errors in the code seen above, it's just that they are neither compilation errors, nor run-time errors that throw exceptions. Plenty can still go wrong with code even if the compiler or virtual machine does not identify them. This is why 'cut & paste' coding sans understanding what the code does, never works. Hit the tutorials and read the Java docs.

How to change icon in JLabel with JButton

I'm making a simple conversion tool to convert dollars to euro's and vice versa.
The whole purpose is just to experiment and learn this cool tool, java.
I have a JLabel at the top with an icon of a euro to indicate the starting currency. I have a button bellow this that I want to use to change that icon to a dollar one.
I am currently plying around with an ActionListener and trying different variations of setIcon/setIconImage (every itteration I can think of seeing that nothing has worked thus far).
public class MoneyConverter extends JFrame implements ActionListener{
//add label and icon showing base conversion currency
JLabel startcur = new JLabel("<--- Starting Curency", new ImageIcon("C:\\Users\\Russel\\Desktop\\1euro.gif"), SwingConstants.CENTER);
JButton euro = new JButton("Swap to Euro");
JButton dollar = new JButton("Swap to Dollar");
I then set up a
public MoneyConverter(){}
method and add all my components to a grid layout and add ActionLister's to my convert buttons.
e.g.
dollar.addActionListener(this);
euro.addActionListener(this);
After the usual code (setVisible and the likes that I will omit for your sake as I don't see it interfering with this, please let me know if I should include it all)
public void ActionPerformed (ActionEvent e){
Object source = e.getSource();
if (source.equals(euro)){
startcur.setIcon(new ImageIcon("C:\\Users\\Russel\\Desktop\\1.gif"));
}
}
This part has been changed many times and is the main reason for this post, how do I change this icon in the JLabel? - I will also be setting the conversion rate in here depending if they choose to start with dollars or euros. (Rate won't be actual rate.)
First, create and store a new ImageIcon
ImageIcon image = new ImageIcon(getClass().getResource("/nameOfImage.jpg"));
Then put this in your Action Listener
label.setIcon(image);
label.setText("");
You have to make sure you have a resource folder set up for your project. You can read how to do that in IntelliJ or Eclipse
You are also declaring the actionPerformed() wrong. I suggest reading up on this You should be doing it like this.
#Override
public void actionPerformed(ActionEvent e)
{
}
Conventionally, in java, method names start with a lower case letter and Classes start with an upper case.
The whole purpose is just to experiment and learn this cool tool, java.
Then I'll show you how to improve this program in a number of ways.
//Don't make your Swing class implement Actionlistener and add it as a
//listener to itself in the constructor before it's fully initialized
public class MoneyConverter extends JFrame {
//These don't have to be loaded at runtime, so make them into constants
//Java variables and methods follow thisNamingConvention
private static final Icon euroIcon = new ImageIcon("C:\\Users\\Russel\\Desktop\\1euro.gif");
private static final Icon dollarIcon = new ImageIcon("C:\\Users\\Russel\\Desktop\\1dollar.gif");
//These you probably want to use later so save them as private class variables
//Make them final so you can access them in the ActionListeners below
private final JLabel currencyLabel;
private final JButton euroButton;
private final JButton dollarButton;
public MoneyConverter() {
//These are declared final and are are therefore usually set first in constructor
this.currencyLabel = new JLabel("<--- Starting Curency", euroIcon, SwingConstants.CENTER);
this.euroButton = new JButton("Swap to Euro");
this.dollarButton = new JButton("Swap to Dollar");
//Write your own separate ActionListener for each button
euroButton.addActionListener(new ActionListener() {
#Override
public void run() {
currencyLabel.setIcon(euroIcon);
//These two are required for you to see the effect
//This should also be the solution to your initial problem
currencyLabel.revalidate();
currencyLabel.repaint();
}
});
dollarButton.addActionListener(new ActionListener() {
#Override
public void run() {
currencyLabel.setIcon(dollarIcon);
currencyLabel.revalidate();
currencyLabel.repaint();
}
});
//Add your components here using whatever layout manager you want.
}
public static void main(String []args){
//Start new Swing applications like this to prevent it from
//clogging the rest of the program
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MoneyConverter();
}
});
}
}

opening JFrame from applet

So I programmed am applet that makes a ball roll in circles for ever, and I wanted to make the user decide what speed the circle should roll in, but something failed when I added the JFrame:
applet(the stop,destroy and update do not appear because they aren't important, and in start there is nothing):
public class Main extends Applet implements Runnable{
private Image I;
private Graphics GfU;
int ballX, ballY=249;
static int radius=20;
double Memory;
int changeY ,changeX=1;
Speed S = new Speed();
#Override
public void init() {
setSize(750,750);
S.setVisible(true);
}
#Override
public void run() {
while(true){
if(ballY>=250 || ballY<=-250){
changeY=0-changeY;
changeX=0-changeX;
}
ballY+=changeY;
Memory=(double)ballY/250;
Memory=Math.asin(Memory);
Memory=Math.cos(Memory);
ballX=(int)(Memory*250);
if(changeX==-1)
ballX=0-ballX;
repaint();
try {
Thread.sleep(17);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void paint(Graphics g) {
g.setColor(Color.black);
g.fillOval(ballX-radius+250, ballY-radius+250, radius*2, radius*2);
}
public void setChangeY(int changeY) {
this.changeY = changeY;
}
public void Done(){
S.setVisible(false);
Thread BallRun = new Thread(this);
BallRun.start();
}
}
JFrame:
public class Speed extends JFrame implements ActionListener{
private static final long serialVersionUID = 1L;
public Speed(){
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel P = new JPanel();
JLabel L = new JLabel("please enter velosity(pixels per second)");
final JTextField TF = new JTextField("00");
final Main M = new Main();
JButton B = new JButton("OK");
B.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
M.setChangeY(Integer.parseInt(TF.getText()));
M.Done();
}
});
P.add(L,BorderLayout.NORTH);
P.add(TF,BorderLayout.WEST);
}
#Override
public void actionPerformed(ActionEvent arg0) {
}
}
thanks (and sorry if it's bothering you the lack of information)
Here are some things to consider:
Don't use a JFrame. Use a JDialog as a popup window. Also, you should probably not create the dialog in the constructor. Instead you should have a JMenuItem so that the user can click on the menu when they want the popup to display.
Don't use "Applet", that is an AWT component. You should be using "JApplet" in a Swing application.
You should not be overriding the paint() method of the applet. Instead you should be adding a JPanel to the applet and then override the paintComponent(...) with your custom painting.
Don't use a loop to control the animation. Instead you should be using a Swing Timer.
Start by reading the Swing tutorial. There are sections on:
How to Make Applets
How to Use Swing Timers
Performing Custom Painting
setDefaultCloseOperation(EXIT_ON_CLOSE);
This is not allowed even in a fully trusted applet. Closing the frame would close the JVM that runs the applet that launched it. That JVM might also be running other applets.
Look at it like this. The web page that hosts an applet is like a guest, while the web page is a guest house. For an applet to end the JVM is like the guest burning down the guest house while smashing out all the windows.
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
Might 'work' (to not produce an AccessControlException), but really, no applet should be launching frames. Use a JDialog instead.
As a general tip: Ensure the Java Console is configured to show for applets & JWS apps. If there is no output at the default level, raise it and try again. Without the information contained in it, I doubt it would be possible to successfully develop an applet.
Your Speed class extends JFrame, but the only things that you set is setDefaultCloseOperation(EXIT_ON_CLOSE), you should set at least se size of your JFrame with setSize(width, height) and set it visible with: setVisible(true).
Another thing... i can't see where you added your JFrame to the Main class...
You should add it creating a new Speed object: Speed objectname = new Speed()
If i've understood correctly that was your problem.
I think you could read here to learn how to use the JFrame: http://www.dreamincode.net/forums/topic/206344-basic-gui-in-java-using-jframes/

Code Executing in different orders, Jframe, Button and TextArea

Basically i have some code to make an interface that allows me to submit a request and it pulls the necessary information from a txt File. For some reason wheni execute my StartUp for the code, sometimes the button isnt there, one text box dominates the screen, all the textboxes overlap... Its weird.
Anyway heres the GUI Code
public class Menu {
SubmitCode submit = new SubmitCode();
public static JFrame frame;
public static JTextField field;
public static Button btn;
public static TextArea txtComm;
public static TextArea txtSites;
public static TextArea txtProg;
public static Dimension dim = new Dimension(40, 10);
public Menu() {
frame = new JFrame();
frame.setTitle("Welcome :)");
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public static void open() {
Menu.main(null); // Opens up the main method of the class
}
public static void main(String args[]) {
field = new JTextField();
btn = new Button();
txtComm = new TextArea();
txtSites = new TextArea();
txtProg = new TextArea();
field.setText("What do you want to do?");
field.setSize(390, 20);
field.setLocation(0, 125);
btn.setVisible(true);
btn.setLabel("Click to Submit");
btn.setSize(90, 20);
btn.setLocation(400, 125);
txtComm.setVisible(true);
txtComm.setText("Commands: ");
txtComm.setSize(150, 100);
txtComm.setLocation(10, 10);
txtComm.setEditable(false);
frame.add(txtComm);
txtSites.setVisible(true);
txtSites.setText("Sites: ");
txtSites.setSize(150, 100);
txtSites.setLocation(170, 10);
txtSites.setEditable(false);
frame.add(txtSites);
txtProg.setVisible(true);
txtProg.setText("Programmes: ");
txtProg.setSize(150, 100);
txtProg.setLocation(330, 10);
txtProg.setEditable(false);
frame.add(txtProg);
frame.setSize(500, 175);
frame.add(field, BorderLayout.SOUTH);
frame.add(btn);
btn.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.out.println("Do Something Clicked");
SubmitCode.main(null);
}
});
}
}
Suggestions:
Don't use static methods/fields, except when a specific need arises or for the main method. You do not have the need here.
Instead use valid classes, classes with constructors, instance (non-static) fields and instance methods.
Don't needlessly mix AWT and Swing components but instead use just Swing components. So JTextArea, not TextArea, JButton, not Button, etc....
For instance, your Menu constructor is wasted code that is never called due to your misuse and over-use of statics.
Don't set sizes, use null layouts and absolute positioning such as with setBounds.
Instead read up on and use the layout managers.
Don't pepper your code with useless bits such as most of your calls to setVisible(true).
Call setVisible(true) on the top level window, here your JFrame, after adding all components.
Do read the relevant tutorials as this is all very well explained there. Google Java Swing Tutorials and check the very first hit.
This bit scares me: SubmitCode.main(null); and suggests that you're trying to call the static main method of another class from within a GUI. You should avoid doing this, and instead have your SubmitCode class use good OOP techniques including non-static methods and fields, constructors, etc...

XOR Painting issue in java

I have a problem with java Xor method:
public class Okno extends JFrame {
public static void main(String[] args) {
Okno okno = new Okno();
}
Window()
{
this.setSize(300,300);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton button= new JButton("Circle");
button.addActionListener(
new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Graphics2D g = (Graphics2D)Window.this.getGraphics();
g.setXORMode(Color.red);
g.setStroke(new BasicStroke(10));
g.drawOval(100, 100, 100, 100);
}
});
this.add("South",button);
this.setVisible(true);
}
It paints circle after second click on button. On Graphic from Image it works fine...
If the code works the second time, odds are good you are calling the code incorrectly. For example, you may be requesting a paint callback and then improperly invalidating the screen area, which means that while the view has changed, the is no event to start the repainting routines.
On the second button click, the paint will then detect the first button click's action, which was to change what is drawn.
Swing painting has changed slightly over the years. You might be stuck with an old tutorial or text. Take a look at the latest online offerings to get a good idea of how it should be done.

Categories

Resources