Reputation: 125
I made a calculator and once I get my answer i want the label l4
to move around the screen continuously. Can anyone show me how to make it move because I cant figure it out.
import java.awt.*;
import java.awt.event.*;
import java.awt.Label;
import java.awt.Font;
import javax.swing.*;
class DanielCalculator implements ActionListener {
Timer t = new Timer(5, this);
int x = 300;
int y = 50;
DanielCalculatorFrame f = new DanielCalculatorFrame();
Label l1 = new Label("First Number");
Label l2 = new Label("Second Number");
Label l3 = new Label("Result: ");
TextField t1 = new TextField();
TextField t2 = new TextField();
Label l4 = new Label("0");
Button b1 = new Button("Add");
Button b2 = new Button("Subtract");
Button b3 = new Button("Multiply");
Button b4 = new Button("Divide");
DanielCalculator()
{
l1.setBounds(20, 70, 100, 20);
l2.setBounds(240, 70, 100, 20);
l3.setBounds(70, 168, 100, 50);
t1.setBounds(120, 70, 100, 20);
t2.setBounds(360, 70, 100, 20);
b1.setBounds(230, 130, 50, 20); //3
b2.setBounds(330, 130, 50, 20); //4
b3.setBounds(30, 130, 50, 20); //1
b4.setBounds(130, 130, 50, 20); //2
f.add(l1);
f.add(l2);
f.add(l3);
f.add(t1);
f.add(t2);
f.add(l4);
f.add(b1);
f.add(b2);
f.add(b3);
f.add(b4);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
b4.addActionListener(this);
f.setLayout(null);
f.setVisible(true);
f.setSize(600,450);
Font myFont = new Font("Serif",Font.BOLD,26);
l4.setFont(myFont);
l3.setFont(myFont);
l4.setBounds(200, 170, x, y);
}
public void actionPerformed(ActionEvent e)
{
double continuee;
Double n1=Double.parseDouble(t1.getText());
Double n2=Double.parseDouble(t2.getText());
if(e.getSource() == b1) {
l4.setText(String.valueOf(n1+n2));\
}
if(e.getSource() == b2) {
l4.setText(String.valueOf(n1-n2));
}
if(e.getSource() == b3) {
l4.setText(String.valueOf(n1*n2));
}
if(e.getSource() == b4) {
l4.setText(String.valueOf(n1/n2));
}
}
public static void main (String[] args) {
new DanielCalculator();
}
}
Upvotes: 1
Views: 4876
Reputation: 7716
There will be countless way to implement a moving JLabel. Here is an instructional example that moves the label on the physical screen. Tweak as necessary.
public class J42JLabel_01 extends JLabel {
private static final long serialVersionUID = -42L;
private JWindow jWindow = null;
private Timer timer = null;
public J42JLabel_01(final String string) {
super(string);
setOpaque(true);
}
public void moveIt(final JFrame jFrame) {
if (jWindow == null) {
jFrame.getContentPane().remove(this);
Toolkit.getDefaultToolkit().beep();
jWindow = new JWindow(jFrame) {
@Override
public void dispose() {
Toolkit.getDefaultToolkit().beep();
timer.cancel();
super.dispose();
}
};
jWindow.setAlwaysOnTop(true);
jWindow.getContentPane().setLayout(new FlowLayout());
jWindow.getContentPane().add(this);
jWindow.pack();
jWindow.setVisible(true);
timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
jWindow.setLocation(jWindow.getLocation().x + 25, jWindow.getLocation().y + 24);
if (jWindow.getLocation().x > Toolkit.getDefaultToolkit().getScreenSize().width / 2) {
jWindow.setLocation(0, 0);
}
if (jWindow.getLocation().y > Toolkit.getDefaultToolkit().getScreenSize().height / 2) {
jWindow.setLocation(0, 0);
}
}
}, 0, 500);
}
else {
jFrame.getContentPane().add(this);
jWindow.dispose();
jWindow = null;
}
}
}
Tester:
J42JLabel_01 instructionalExample = new J42JLabel_01(" TEST TESTING TEST ");
final JFrame jFrame = new JFrame();
jFrame.getContentPane().add(new JButton("Click") {
{
jFrame.getContentPane().add(this);
addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
instructionalExample.moveIt(jFrame);
jFrame.repaint();
jFrame.validate();
}
});
}
});
jFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jFrame.setLayout(new FlowLayout());
jFrame.getContentPane().add(instructionalExample);
jFrame.pack();
jFrame.setLocationRelativeTo(null);
jFrame.setVisible(true);
Upvotes: 1
Reputation: 347334
Probably the simplest solution would be to use the frame's glass pane, as it allows you to control the layout independently of the main view.
Speaking of layouts...this is why you should avoid null
layouts...
This example uses the frame's glass pane capabilities to provide an animation layer which will appear above the main UI
The ResultsPane
does make use of null
layout, this is the only way you can provide this type of functionality, but what it does is makes sure it honours the component's preferred size, allowing for differences in fonts, font metrics and other rendering differences that could affect the size on other platforms...
The base calculation pane makes use of a compound layout approach, where the fields and buttons are laid out independently of each other.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import javax.swing.AbstractAction;
import static javax.swing.Action.NAME;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestCalculator {
public static void main(String[] args) {
new TestCalculator();
}
public TestCalculator() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
ResultPane resultPane = new ResultPane();
JFrame frame = new JFrame("Testing");
frame.setGlassPane(resultPane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new CalculatorPane(resultPane));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ResultPane extends JPanel {
private JLabel result;
private Timer timer;
private int xDelta = (Math.random() > 0.5) ? 1 : -1;
private int yDelta = (Math.random() > 0.5) ? 1 : -1;
;
public ResultPane() {
setOpaque(false);
setLayout(null);
result = new JLabel();
Font font = result.getFont();
font = font.deriveFont(Font.BOLD, 26f);
result.setFont(font);
add(result);
timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Point point = result.getLocation();
point.x += xDelta;
point.y += yDelta;
if (point.x < 0) {
point.x = 0;
xDelta *= -1;
} else if (point.x + result.getWidth() > getWidth()) {
point.x = getWidth() - result.getWidth();
xDelta *= -1;
}
if (point.y < 0) {
point.y = 0;
yDelta *= -1;
} else if (point.y + result.getHeight() > getHeight()) {
point.y = getHeight() - result.getHeight();
yDelta *= -1;
}
result.setLocation(point);
repaint();
}
});
timer.start();
}
public void setResult(Number number) {
result.setText("Result: " + NumberFormat.getNumberInstance().format(number));
result.setSize(result.getPreferredSize());
setVisible(true);
}
}
public class CalculatorPane extends JPanel {
private final ResultPane resultPane;
private final JLabel firstNumberLabel = new JLabel("First Number:");
private final JLabel secondNumberLabel = new JLabel("Second Number:");
private final JTextField firstNumberField = new JTextField(5);
private final JTextField secondNumberField = new JTextField(5);
public CalculatorPane(ResultPane resultPane) {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
this.resultPane = resultPane;
JPanel fields = new JPanel();
fields.add(firstNumberLabel);
fields.add(firstNumberField);
fields.add(secondNumberLabel);
fields.add(secondNumberField);
add(fields, gbc);
JPanel buttons = new JPanel();
buttons.add(new JButton(new AddAction()));
buttons.add(new JButton(new SubtractAction()));
buttons.add(new JButton(new MultiplyAction()));
buttons.add(new JButton(new DivideAction()));
add(buttons, gbc);
}
public class AddAction extends AbstractAction {
public AddAction() {
putValue(NAME, "+");
}
@Override
public void actionPerformed(ActionEvent e) {
try {
double num1 = Double.parseDouble(firstNumberField.getText());
double num2 = Double.parseDouble(secondNumberField.getText());
double result = num1 + num2;
resultPane.setResult(result);
} catch (NumberFormatException exp) {
}
}
}
public class SubtractAction extends AbstractAction {
public SubtractAction() {
putValue(NAME, "-");
}
@Override
public void actionPerformed(ActionEvent e) {
try {
double num1 = Double.parseDouble(firstNumberField.getText());
double num2 = Double.parseDouble(secondNumberField.getText());
double result = num1 - num2;
resultPane.setResult(result);
} catch (NumberFormatException exp) {
}
}
}
public class MultiplyAction extends AbstractAction {
public MultiplyAction() {
putValue(NAME, "x");
}
@Override
public void actionPerformed(ActionEvent e) {
try {
double num1 = Double.parseDouble(firstNumberField.getText());
double num2 = Double.parseDouble(secondNumberField.getText());
double result = num1 * num2;
resultPane.setResult(result);
} catch (NumberFormatException exp) {
}
}
}
public class DivideAction extends AbstractAction {
public DivideAction() {
putValue(NAME, "/");
}
@Override
public void actionPerformed(ActionEvent e) {
try {
double num1 = Double.parseDouble(firstNumberField.getText());
double num2 = Double.parseDouble(secondNumberField.getText());
double result = num1 / num2;
resultPane.setResult(result);
} catch (NumberFormatException exp) {
}
}
}
}
}
Take a look at How to Use Root Panes for more details
Don't use null
layouts. Pixel perfect layouts are an illusion in modern UI design, you have no control over fonts, DPI, rendering pipelines or other factors that will change the way that you components will be rendered on the screen.
Swing was designed to work with layout managers to overcome these issues. If you insist on ignoring these features and work against the API design, be prepared for a lot of headaches and never ending hard work...
Upvotes: 3