I'm trying to make a JLabel move across other JLabels, only 1 timer works right now. It is supposed to operate like a train moving across a track, going all the way around the track and ending up right back where it started from. I'm not sure how to make it go all the way around, any help is appreciated.
Thank you.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.JTextField;
import java.awt.Color;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;
public class MoveLabel {
private JTextField textField;
private JTextField tf;
private JTextField textField_1;
private JTextField textField_2;
private JTextField textField_3;
private JTextField textField_5;
private JTextField textField_6;
private JTextField textField_7;
private JTextField textField_8;
private JTextField textField_9;
private JTextField textField_10;
private JTextField textField_11;
private JTextField textField_12;
private JTextField textField_13;
private JTextField textField_14;
private JTextField textField_15;
private JTextField textField_16;
private JTextField textField_17;
private JTextField textField_18;
private JTextField textField_19;
private JTextField textField_20;
private JTextField textField_21;
private JTextField textField_22;
private JTextField textField_23;
private JTextField textField_24;
private JTextField textField_25;
private JTextField textField_26;
private JSlider slider;
private JSlider slider_1;
private JSlider slider_2;
public static void main(String[] args) {
new MoveLabel();
}
public MoveLabel() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
TestPane testPane = new TestPane();
testPane.setBackground(Color.WHITE);
frame.getContentPane().add(testPane);
textField = new JTextField();
textField.setBounds(100, 138, 20, 20);
testPane.add(textField);
textField.setColumns(10);
textField_1 = new JTextField();
textField_1.setColumns(10);
textField_1.setBounds(80, 44, 20, 20);
testPane.add(textField_1);
textField_2 = new JTextField();
textField_2.setColumns(10);
textField_2.setBounds(120, 44, 20, 20);
testPane.add(textField_2);
textField_3 = new JTextField();
textField_3.setColumns(10);
textField_3.setBounds(160, 44, 20, 20);
testPane.add(textField_3);
textField_5 = new JTextField();
textField_5.setColumns(10);
textField_5.setBounds(140, 138, 20, 20);
testPane.add(textField_5);
textField_6 = new JTextField();
textField_6.setColumns(10);
textField_6.setBounds(160, 138, 20, 20);
testPane.add(textField_6);
textField_7 = new JTextField();
textField_7.setColumns(10);
textField_7.setBounds(120, 138, 20, 20);
testPane.add(textField_7);
textField_8 = new JTextField();
textField_8.setColumns(10);
textField_8.setBounds(80, 59, 20, 20);
testPane.add(textField_8);
textField_9 = new JTextField();
textField_9.setColumns(10);
textField_9.setBounds(80, 75, 20, 20);
testPane.add(textField_9);
textField_10 = new JTextField();
textField_10.setColumns(10);
textField_10.setBounds(80, 90, 20, 20);
testPane.add(textField_10);
textField_11 = new JTextField();
textField_11.setColumns(10);
textField_11.setBounds(80, 106, 20, 20);
testPane.add(textField_11);
textField_12 = new JTextField();
textField_12.setColumns(10);
textField_12.setBounds(80, 123, 20, 20);
testPane.add(textField_12);
textField_13 = new JTextField();
textField_13.setColumns(10);
textField_13.setBounds(179, 44, 20, 20);
testPane.add(textField_13);
textField_14 = new JTextField();
textField_14.setColumns(10);
textField_14.setBounds(199, 44, 20, 20);
testPane.add(textField_14);
textField_15 = new JTextField();
textField_15.setColumns(10);
textField_15.setBounds(80, 138, 20, 20);
testPane.add(textField_15);
textField_16 = new JTextField();
textField_16.setColumns(10);
textField_16.setBounds(100, 44, 20, 20);
testPane.add(textField_16);
textField_17 = new JTextField();
textField_17.setColumns(10);
textField_17.setBounds(140, 44, 20, 20);
testPane.add(textField_17);
textField_18 = new JTextField();
textField_18.setColumns(10);
textField_18.setBounds(179, 138, 20, 20);
testPane.add(textField_18);
textField_19 = new JTextField();
textField_19.setColumns(10);
textField_19.setBounds(199, 138, 20, 20);
testPane.add(textField_19);
textField_20 = new JTextField();
textField_20.setColumns(10);
textField_20.setBounds(219, 63, 20, 20);
testPane.add(textField_20);
textField_21 = new JTextField();
textField_21.setColumns(10);
textField_21.setBounds(219, 138, 20, 20);
testPane.add(textField_21);
textField_22 = new JTextField();
textField_22.setBackground(Color.WHITE);
textField_22.setColumns(10);
textField_22.setBounds(219, 44, 20, 20);
testPane.add(textField_22);
textField_23 = new JTextField();
textField_23.setColumns(10);
textField_23.setBounds(219, 123, 20, 20);
testPane.add(textField_23);
textField_24 = new JTextField();
textField_24.setColumns(10);
textField_24.setBounds(219, 99, 20, 27);
testPane.add(textField_24);
textField_25 = new JTextField();
textField_25.setColumns(10);
textField_25.setBounds(219, 83, 20, 20);
testPane.add(textField_25);
textField_26 = new JTextField();
textField_26.setColumns(10);
textField_26.setBounds(219, 90, 20, 20);
testPane.add(textField_26);
slider_2 = new JSlider();
slider_2.setMaximum(3);
slider_2.setPaintTicks(true);
slider_2.setSnapToTicks(true);
slider_2.setOrientation(SwingConstants.VERTICAL);
slider_2.setBounds(533, 260, 57, 229);
testPane.add(slider_2);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
protected static final int PLAY_TIME = 4000;
private JLabel label;
private JTextField tf;
private int targetX;
private int targetY;
private int targetX2;
private int targetY2;
private long startTime;
private long startTime2;
private final int startX;
private final int startY;
private final int startX2;
private final int startY2;
public TestPane() {
setLayout(null);
tf = new JTextField("");
tf.setSize(20,20);
tf.setBackground(Color.red);
add(tf);
Dimension size = getPreferredSize();
startX = 80;
startY = 44;
/* targetX = (size.width - label.getSize().width) / 2;
targetY = (size.height - label.getSize().height) / 2;
*/
targetX = 140;
targetY = 44;
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int x = tf.getX();
int y = tf.getY();
long duration = System.currentTimeMillis() - startTime;
float progress = (float)duration / (float)PLAY_TIME;
if (progress > 1f) {
progress = 1f;
((Timer)(e.getSource())).stop();
}
x = startX + (int)Math.round((targetX - startX) * progress);
y = startY + (int)Math.round((targetY - startY) * progress);
tf.setLocation(x, y);
}
});
startTime = System.currentTimeMillis();
timer.start();
/* try {
Thread.sleep(10);
}
catch (InterruptedException ie) {
ie.printStackTrace();
}
if (timer.isRunning() != true)
{
timer.stop();
}*/
startX2 = targetX;
startY2 = targetY;
tf.setLocation(startX,startY);
/* targetX = (size.width - label.getSize().width) / 2;
targetY = (size.height - label.getSize().height) / 2;
*/
targetX2 = 219;
targetY2 = 44;
Timer timer2 = new Timer(40, new ActionListener() {
public void actionPerformed(ActionEvent e) {
int x2 = tf.getX();
int y2 = tf.getY();
long duration = System.currentTimeMillis() - startTime2;
float progress = (float)duration / (float)PLAY_TIME;
if (progress > 1f)
{
progress = 1f;
((Timer)(e.getSource())).stop();
}
x2 = startX2 + (int)Math.round((targetX2 - startX2) * progress);
y2 = startY2 + (int)Math.round((targetY2 - startY2) * progress);
tf.setLocation(x2, y2);
tf.getLocation();
}
});
startTime2 = System.currentTimeMillis();
if (timer.isRunning() == false)
{
//
timer2.start();
}
else
{
timer2.setDelay(10);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(600, 500);
}
}
}
nb: I don't like null layouts, I don't condone null layouts, I would prefer to have used custom painting, but that's a lot of work not related to the question. This example is intended to focus on the implementation of a Timeline and KeyFrame animation
Because you have to move the object through both the x/y positions, but in different directions over the same time period, this becomes a very complex problem...
You could try and set up four, chained Timers, which trigger the next Timer when they complete, and which all do a different part of the animation...but frankly, that becomes a mess real quick...
A better idea is to use a concept of a time line and key frames. The idea is, that over the time line (0-1), certain events occur at prescribed times (key frames). The time line will then blend between these key frames...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MoveLabel {
public static void main(String[] args) {
new MoveLabel();
}
public MoveLabel() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
TestPane testPane = new TestPane();
testPane.setBackground(Color.WHITE);
frame.getContentPane().add(testPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
private JTextField tf;
private List<JTextField> tracks;
protected static final int PLAY_TIME = 4000;
private Timeline timeline;
private long startTime;
public TestPane() {
setLayout(null);
tracks = new ArrayList<JTextField>(20);
int x = 20;
int y = 20;
for (int index = 0; index < 6; index++) {
x += 20;
tracks.add(createTrack(x, y, 20, 20));
}
for (int index = 0; index < 6; index++) {
y += 20;
tracks.add(createTrack(x, y, 20, 20));
}
for (int index = 0; index < 6; index++) {
x -= 20;
tracks.add(createTrack(x, y, 20, 20));
}
for (int index = 0; index < 6; index++) {
y -= 20;
tracks.add(createTrack(x, y, 20, 20));
}
for (JTextField track : tracks) {
add(track);
}
tf = new JTextField("");
tf.setSize(20, 20);
tf.setBackground(Color.red);
add(tf);
setComponentZOrder(tf, 0);
timeline = new Timeline();
timeline.add(0, new Point(20, 20));
timeline.add(0.25f, new Point(20 * 7, 20));
timeline.add(0.5f, new Point(20 * 7, 20 * 7));
timeline.add(0.75f, new Point(20, 20 * 7));
timeline.add(1f, new Point(20, 20));
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
long duration = System.currentTimeMillis() - startTime;
float progress = (float) duration / (float) PLAY_TIME;
if (progress > 1f) {
startTime = System.currentTimeMillis();
progress = 0;
// ((Timer) (e.getSource())).stop();
}
Point p = timeline.getPointAt(progress);
tf.setLocation(p);
}
});
startTime = System.currentTimeMillis();
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(600, 500);
}
protected JTextField createTrack(int x, int y, int width, int height) {
JTextField field = new JTextField();
field.setBounds(x, y, width, height);
field.setEditable(false);
field.setFocusable(false);
return field;
}
}
public static class Timeline {
private Map<Float, KeyFrame> mapEvents;
public Timeline() {
mapEvents = new TreeMap<>();
}
public void add(float progress, Point p) {
mapEvents.put(progress, new KeyFrame(progress, p));
}
public Point getPointAt(float progress) {
if (progress < 0) {
progress = 0;
} else if (progress > 1) {
progress = 1;
}
KeyFrame[] keyFrames = getKeyFramesBetween(progress);
float max = keyFrames[1].progress - keyFrames[0].progress;
float value = progress - keyFrames[0].progress;
float weight = value / max;
return blend(keyFrames[0].getPoint(), keyFrames[1].getPoint(), 1f - weight);
}
public KeyFrame[] getKeyFramesBetween(float progress) {
KeyFrame[] frames = new KeyFrame[2];
int startAt = 0;
Float[] keyFrames = mapEvents.keySet().toArray(new Float[mapEvents.size()]);
while (startAt < keyFrames.length && keyFrames[startAt] <= progress) {
startAt++;
}
if (startAt >= keyFrames.length) {
startAt = keyFrames.length - 1;
}
frames[0] = mapEvents.get(keyFrames[startAt - 1]);
frames[1] = mapEvents.get(keyFrames[startAt]);
return frames;
}
protected Point blend(Point start, Point end, float ratio) {
Point blend = new Point();
float ir = (float) 1.0 - ratio;
blend.x = (int)(start.x * ratio + end.x * ir);
blend.y = (int)(start.y * ratio + end.y * ir);
return blend;
}
public class KeyFrame {
private float progress;
private Point point;
public KeyFrame(float progress, Point point) {
this.progress = progress;
this.point = point;
}
public float getProgress() {
return progress;
}
public Point getPoint() {
return point;
}
}
}
}
You could then do silly things like vary the speed between sections...
timeline = new Timeline();
timeline.add(0, new Point(20, 20));
timeline.add(0.1f, new Point(20 * 7, 20));
timeline.add(0.5f, new Point(20 * 7, 20 * 7));
timeline.add(0.6f, new Point(20, 20 * 7));
timeline.add(1f, new Point(20, 20));
Related
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.*;
public class NewJFrame extends JFrame {
private Graphics g1;
private JLabel label = new JLabel();
// holds information of all businesses
private Object[][] busInfo = new Object[10][15];
public NewJFrame() {
initComponents();
g1 = jPanel1.getGraphics();
}
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 858, Short.MAX_VALUE));
jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 564, Short.MAX_VALUE));
jButton1.setText("Click Me");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(
javax.swing.GroupLayout.Alignment.TRAILING,
layout.createSequentialGroup().addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton1).addGap(425, 425, 425))
.addGroup(layout.createSequentialGroup().addGap(48, 48, 48)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(61, Short.MAX_VALUE)));
layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup().addGap(28, 28, 28)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(jButton1)));
pack();
}// </editor-fold>
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
printBarChart(2, 1);
System.out.println(getSize());
}
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(() -> {
new NewJFrame().setVisible(true);
});
}
public void printBarChart(int bestBus, int worstBus) {
busInfo[0][7] = 24325.08;
busInfo[1][7] = 15394.59;
busInfo[2][7] = 186719.84;
int y = jPanel1.getSize().height;
int x = jPanel1.getSize().width;
double balance, maxScale = (double) busInfo[bestBus][7] + 650;
int sameBusDistance, diffBusDistance = 0, scaleNum, maxPoint;
for (int i = 0; i <= 2; ++i) {
if (i == 0) {
diffBusDistance = 0;
} else {
diffBusDistance += 65;
}
// color of best business
if (i == bestBus) {
g1.setColor(Color.YELLOW);
// color of worst business
} else if (i == worstBus) {
g1.setColor(Color.RED);
// color of other businesses (neither best nor worst)
} else {
g1.setColor(Color.BLACK);
}
balance = (double) busInfo[i][7];
sameBusDistance = 25;
scaleNum = y - 100;
maxPoint = scaleNum - (scaleNum * (int) balance / (int) maxScale) + 50;
g1.drawLine(125 + diffBusDistance, y - 50, 125 + diffBusDistance, maxPoint);
g1.drawLine(125 + sameBusDistance + diffBusDistance, y - 50, 125 + sameBusDistance + diffBusDistance,
maxPoint);
g1.drawLine(125 + sameBusDistance + diffBusDistance, maxPoint, 125 + diffBusDistance, maxPoint);
jPanel1.add(label);
jPanel1.setLayout(null);
label.setSize(100, 50);
label.setFont(label.getFont().deriveFont(8f));
label.setLocation(125 + sameBusDistance + diffBusDistance - 30, maxPoint - 50);
label.setText("" + busInfo[i][7]);
}
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JPanel jPanel1;
// End of variables declaration
}
Line drawn by Graphics type variable disappears when making a label for it
This code is in a for loop for the number of businesses. I will attach a picture of the problem.The first bar works just fine:
The second however removes the first bar and its label from view:
Printing labels for Bar Charts causing other bars and their labels to dissapear
Again, I suggest that you don't use getGraphics() called on a component. By now you should have minimized and restored your GUI to see that the drawing is not stable when you minimize and restore the GUI. I suggest that you draw in the paintComponent of your JPanel.
There is an exception however -- if you draw in a BufferedImage, you can use a Graphics object obtained from it, and then display the image in an ImageIcon in a JLabel. For example in the code below I create a JLabel filled with an empty image (to give it size). I then fill the image with some bar chart data on button press, put the image into an ImageIcon and then set the JLabel with that icon by calling setIcon(...) on it:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import javax.swing.*;
#SuppressWarnings("serial")
public class DrawInImage extends JPanel {
private static final int IMG_W = 900;
private static final int IMG_H = 700;
private static final int GAP = 20;
private BufferedImage img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB);
private Icon icon = new ImageIcon(img);
private JLabel label = new JLabel(icon);
private int[] data = { 4, 2, 9, 7, 3, 8, 2, 8 };
public DrawInImage() {
JPanel btnPanel = new JPanel();
btnPanel.add(new JButton(new AbstractAction("Press Me") {
#Override
public void actionPerformed(ActionEvent arg0) {
printBarChart();
}
}));
setLayout(new BorderLayout());
add(label);
add(btnPanel, BorderLayout.PAGE_END);
}
private void printBarChart() {
// create new image
img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics(); // get image's graphics
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 18));
// get sizes of drawing area
int totalWidth = IMG_W - 2 * GAP;
int totalHeight = IMG_H - 2 * GAP;
// number of columns including gaps
int columns = 2 * data.length + 1;
// calc the max data + 1
int maxData = 0;
for (int i : data) {
if (i > maxData) {
maxData = i;
}
}
maxData++; // + 1
for (int i = 0; i < data.length; i++) {
int x1 = GAP + ((2 * i + 1) * totalWidth) / columns;
int x2 = GAP + ((2 * i + 2) * totalWidth) / columns;
int y1 = GAP + (totalHeight * (maxData - data[i])) / maxData;
int y2 = GAP + totalHeight;
float hue = (float) i / (float) data.length;
Color c = Color.getHSBColor(hue, 1f, 1f);
g2.setColor(c);
g2.fillRect(x1, y1, x2 - x1, y2 - y1);
g2.setColor(Color.BLACK);
String text = "Data " + (i + 1);
int strX = x1;
int strY = y1 - GAP / 2;
g2.drawString(text, strX, strY);
}
g2.dispose(); // dispose of graphics objects *we* create
icon = new ImageIcon(img); // create new icon
label.setIcon(icon); // display in label
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Draw In Image");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new DrawInImage());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
Which displays as
I'm trying to make a goal organizer program and want to be able to zoom in and out with the buttons moving with the border of the rectangle, but when I press the zoom in or out button it leaves the original where it is and creates a new one over it. Also the buttons are shown in the position I coded for, but they also show up at the top of the screen.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Screen extends JPanel implements Runnable{
/**
*
*/
private static final long serialVersionUID = 1L;
Frame frame;
Thread thread = new Thread(this);
public JButton one;
public JButton two;
public JButton zoomIn;
public JButton zoomOut;
public JButton next;
public JButton xv;
int buttonW = 100;
int buttonH = 50;
int zoomLevel = 5;
int fps;
public boolean running = true;
public Screen(Frame frame) {
this.frame = frame;
thread.start();
}
public void run() {
long lastFrame = System.currentTimeMillis();
int frames = 0;
running = true;
while(running){
repaint();
frames++;
if(System.currentTimeMillis() - 1000 >= lastFrame){
fps = frames;
frames = 0;
lastFrame = System.currentTimeMillis();
}
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void paintComponent(Graphics g){
Color bgc = new Color (192,192,192);
int screenW = this.getWidth();
int screenH = this.getHeight();
int centerH = screenH / 2;
int centerW = screenW / 2;
g.setColor(bgc);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
/*---------------------------button-stuff------------------------------ **/
Icon plus = new ImageIcon("res/buttons/plus.png");
Icon minus = new ImageIcon("res/buttons/minus.png");
/*---------------------------zoom buttons------------------------------**/
zoomOut = new JButton("", minus);
zoomOut.setBounds(screenW - 30, 32, 20, 20);
zoomOut.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
buttonH = buttonH-10;
buttonW = buttonW-20;
zoomLevel = zoomLevel-1;
}
});
zoomIn = new JButton("", plus);
zoomIn.setBounds(screenW - 30, 10, 20, 20);
zoomIn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
buttonH = buttonH+10;
buttonW = buttonW+20;
zoomLevel = zoomLevel+1;
}
});
/*------------------------------------Next--------------------------------------------------------**/
next = new JButton("");
next.setBounds(centerW + ((buttonW / 2) - 5), centerH - 5, 10, 10);
next.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
JButton oo = new JButton("new");
oo.setBounds(10,10,10,10);
add(oo);
}
});
xv = new JButton("");
add(xv);
xv.setBounds(centerW -10, centerH - ((buttonH / 2) + 10), 20, 20);
/*------------------------------Add Buttons----------------------------------------------------------**/
add(zoomOut);
add(zoomIn);
add(next);
g.setColor(Color.GREEN);
g.fillRect(centerW - (buttonW / 2), centerH - (buttonH / 2), buttonW, buttonH);
}
}
I created a Class with JPanel extended to it. Then when I created an object of it and added to an existing JPanel, it doesn't show up. What am I doing wrong here?
public class StartTower extends JPanel{
private int value;
public StartTower(int value){
this.value = value;
}
public static StartTower send(int value){
return new StartTower(value);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(752, 359);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillRect(120, 60, 10, 270);
g.fillRect(20, 330, 210, 10);
g.fillRect(375, 60, 10, 270);
g.fillRect(275, 330, 210, 10);
g.fillRect(630, 60, 10, 270);
g.fillRect(530, 330, 210, 10);
int val1 = 20;
int val2 = 315;
int val3 = 210;
int col = 100;
for (int i = 0; i < value; i++) {
g.setColor(new Color(100, col, 100));
g.fillRect(val1, val2, val3, 15);
System.out.println(val1 + " " + val2 + " " + val3 + " " + col);
val1 += 10;
val2 -= 15;
val3 -= 20;
col -= 10;
}
}
}
Class with JPanel extended
private void startBtActionPerformed(java.awt.event.ActionEvent evt) {
//mainPanel.repaint();
name = javax.swing.JOptionPane.showInputDialog(rootPane, "Enter you name!", "Ready?", WIDTH);
if (name != null) {
clockFunc(true);
game.initialDisk((int) disksSpinner.getValue());
StartTower startTower = new StartTower((int) disksSpinner.getValue());
mainPanel.setLayout(null);
this.add(startTower);
a2bBt.setEnabled(true);
a2cBt.setEnabled(true);
b2aBt.setEnabled(true);
b2cBt.setEnabled(true);
c2aBt.setEnabled(true);
c2bBt.setEnabled(true);
optimumLabel.setText(getNoOfOptimumMoves((int) disksSpinner.getValue()));
disksSpinner.setEnabled(false);
startBt.setEnabled(false);
}
}
Method where I made the object of the before said class and added it to the existing JPanel. (mainPanel is the existing JPanel created using drag drop in NetBeans).
Why isn't this showing up? What's wrong in the code? Thanks in advance!
I'm not sure what's your complete code, but I just tried this and it works fine:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class StartTower extends JPanel
{
private int value;
public StartTower(int value)
{
this.value = value;
}
public static StartTower send(int value)
{
return new StartTower(value);
}
#Override
public Dimension getPreferredSize()
{
return new Dimension(752, 359);
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.fillRect(120, 60, 10, 270);
g.fillRect(20, 330, 210, 10);
g.fillRect(375, 60, 10, 270);
g.fillRect(275, 330, 210, 10);
g.fillRect(630, 60, 10, 270);
g.fillRect(530, 330, 210, 10);
int val1 = 20;
int val2 = 315;
int val3 = 210;
int col = 100;
for (int i = 0; i < value; i++)
{
g.setColor(new Color(100, col, 100));
g.fillRect(val1, val2, val3, 15);
System.out.println(val1 + " " + val2 + " " + val3 + " " + col);
val1 += 10;
val2 -= 15;
val3 -= 20;
col -= 10;
}
}
private static void createAndShowGUI()
{
StartTower startTower = new StartTower(5);
JFrame jFrame = new JFrame();
JPanel jPanel = new JPanel();
jPanel.add(startTower);
jFrame.getContentPane().add(jPanel);
jFrame.pack();
jFrame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
If you are going to use null layout, which I don't recommend, then before you add a component you have to set its bounds so the null layout knows where to put it.
Doing without a layout
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have 2 classes, one which extends a panel and other which extends a frame.
First class, the panel(used for drawings):
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class GraficPne extends JPanel{
public int dim1 = 0, dim2 = 0;
public JLabel lblSem1GraficPne, lblSem2GraficPne;
public GraficPne(){
super();
this.setLayout(null);
this.setupComponents();
}
public void setupComponents(){
lblSem1GraficPne = new JLabel("Sem I");
lblSem2GraficPne = new JLabel("Sem II");
lblSem1GraficPne.setFont(new Font("Serif", Font.PLAIN, 12));
lblSem2GraficPne.setFont(new Font("Serif", Font.PLAIN, 12));
this.add(lblSem1GraficPne);
this.add(lblSem2GraficPne);
}
public void layComponents(int firstConv, int secondConv){
lblSem1GraficPne.setBounds(20, getHeight() - firstConv - 20, 100, 20);
lblSem2GraficPne.setBounds(100, getHeight() - secondConv - 20, 100, 20);
}
public void paint(Graphics g){
super.paint(g);
g.setColor(Color.BLACK);
g.drawRect(0, 0, getWidth()-1, getHeight()-1);
this.setBackground(Color.GREEN);
g.setColor(Color.RED);
g.fillRect(20, getHeight()-dim1, 40, dim1);
g.setColor(Color.BLUE);
g.fillRect(100, getHeight()-dim2, 40, dim2);
}
public void setData(int dim1, int dim2){
this.dim1 = dim1;
this.dim2 = dim2;
}
}
Second class, the frame, used to add the panel on it:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class GraficFrm extends JFrame implements ActionListener{
private JButton btnApply;
private JLabel lblSem1, lblSem2;
private JTextField txtSem1, txtSem2;
private GraficPne ob; //the object from first class
private int firstConv = 0, secondConv = 0;
public GraficFrm() {
super("Grafic soft");
initSettings();
setupComponents();
}
private void initSettings() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
this.setSize(400, 450);
this.setLocation(100, 100);
this.setResizable(false);
}
private void setupComponents() {
ob = new GraficPne();
lblSem1 = new JLabel("Sem I");
txtSem1 = new JTextField();
lblSem2 = new JLabel("Sem II");
txtSem2 = new JTextField();
btnApply = new JButton("Apply");
ob.setBounds(30, 50, 340, 200);
lblSem1.setBounds(30, 280, 100, 20);
txtSem1.setBounds(150, 280, 220, 20);
lblSem2.setBounds(30, 330, 100, 20);
txtSem2.setBounds(150, 330, 220, 20);
btnApply.setBounds(170, 380, 80, 30);
this.add(lblSem1);
this.add(ob);
this.add(txtSem1);
this.add(lblSem2);
this.add(txtSem2);
this.add(btnApply);
btnApply.addActionListener(this);
}
public void getConvertedValues(){
String txtField1 = txtSem1.getText();
firstConv = Integer.parseInt(txtField1);
String txtField2 = txtSem2.getText();
secondConv = Integer.parseInt(txtField2);
}
public void getHighValues(){
if((firstConv > 100) || (secondConv > 100)) {
JOptionPane.showMessageDialog(this, "Only values < 100 are allowed");
firstConv = 0;
secondConv = 0;
txtSem1.setText("");
txtSem2.setText("");
ob.removeAll();
ob.repaint();
}
}
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(btnApply)){
try{
new GraficFrm();
getConvertedValues();
getHighValues();
ob.setData(firstConv, secondConv);
ob.layComponents(firstConv,secondConv);
ob.repaint();
}catch(NumberFormatException ex1){
JOptionPane.showMessageDialog(this, "Only natural numbers are allowed");
}
}
}
public static void main(String[] args) {
GraficFrm frm = new GraficFrm();
frm.setVisible(true);
}
}
All I want to do is to create a new method called getNegativeValues(), which would be called by pressing the Apply button, and this method to be executed when firstConv or secondConv would be < than 0. The block of my method, getNegativeValues(), i want to keep only the green background of the panel, as it is in paint(Graphics g), but to draw a center horizontal line(g.drawLine(0, getHeight()/2, getWidth(), getHeight()/2);). Then, when i execute the program and i type, let's say the value 55 for the first textfield and -40 for the second one, to draw 55 over my center horizontal line and -40 under my center horizontal line, and the 0 point would be on this center horizontal line.
LE:
#nIcE cOw i'll make a short recap: So, first, when i execute my app, i just want to appear my green panel and those 2 labels which have 2 textfields, as in my example(try to follow my example, please)(all good, i already did this, so this part is done). After, when i complete those 2 textfields let's say with 2 positive values, and then when i press the Apply button to happen exactly like in my example(without any center vertical line)(so already did this, also). All good, but my problem is: If complete one of those 2 textfields with a negative value and other with a positive one, and after i press the Apply button, i want that my application to recognize that there is a negative value typped in one of my textfields, thus to draw me on my green panel a center horizontal line(after i press the Apply button) and to draw those 2 rectangles exactly as you did in your first picture uploaded. Please help me, as i said i'll help you to understand what i want to do, and also i want to say i really appreciate your effort and i'm sorry (again) if i was confused(again).
I guess, what you looking for is a method as presented below, that might can calculate, the starting point of Rectangles that you are trying to draw on the JPanel. Here pos is Positive Value and neg is Negative Value:
public void setValues(int above, int below)
{
midPoint = getHeight() / 2;
heightAbove = Math.abs(above);
heightBelow = Math.abs(below);
/*
* If both are negative values,
* we need a Mid-Point in this case.
*/
if (above < 0 && below < 0)
{
rectAbove = midPoint;
diff = 120;
rectBelow = midPoint;
flag = true;
}
else if (above >= 0 && below >= 0)
{
rectAbove = getHeight() - heightAbove;
diff = 120;
rectBelow = getHeight() - heightBelow;
flag = false;
}
else if (above < 0 && below >= 0)
{
rectAbove = midPoint;
diff = 40;
rectBelow = midPoint - heightBelow;
flag = true;
}
else if (above >= 0 && below < 0)
{
rectAbove = midPoint - heightAbove;
diff = 40;
rectBelow = midPoint;
flag = true;
}
repaint();
}
Here is the code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PaintingRectangles
{
private JTextField aboveField;
private JTextField belowField;
private JButton applyButton;
private MyCanvas canvas;
private void displayGUI()
{
JFrame frame = new JFrame("Painting Rectangles Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
JPanel rightPanel = new JPanel();
rightPanel.setLayout(new GridLayout(3, 1, 5, 5));
aboveField = new JTextField(10);
belowField = new JTextField(10);
applyButton = new JButton("Apply");
applyButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
int above = 0;
int below = 0;
try
{
above = Integer.parseInt(aboveField.getText());
below = Integer.parseInt(belowField.getText());
}
catch(NumberFormatException nfe)
{
aboveField.setText("0");
belowField.setText("0");
above = 0;
below = 0;
nfe.printStackTrace();
}
canvas.setValues(above, below);
}
});
rightPanel.add(aboveField);
rightPanel.add(belowField);
rightPanel.add(applyButton);
canvas = new MyCanvas();
contentPane.add(canvas, BorderLayout.CENTER);
contentPane.add(rightPanel, BorderLayout.LINE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new PaintingRectangles().displayGUI();
}
});
}
}
class MyCanvas extends JPanel
{
private int midPoint = getHeight() / 2;
private int rectAbove = getHeight() / 2;
private int rectBelow = getHeight() / 2;
private int width = 40;
private int heightAbove = 0;
private int heightBelow = 0;
private int diff = 0;
private boolean flag = false;
public MyCanvas()
{
setBackground(Color.GREEN);
}
public void setValues(int above, int below)
{
midPoint = getHeight() / 2;
heightAbove = Math.abs(above);
heightBelow = Math.abs(below);
/*
* If both are negative values,
* we need a Mid-Point in this case.
*/
if (above < 0 && below < 0)
{
rectAbove = midPoint;
diff = 120;
rectBelow = midPoint;
flag = true;
}
else if (above >= 0 && below >= 0)
{
rectAbove = getHeight() - heightAbove;
diff = 120;
rectBelow = getHeight() - heightBelow;
flag = false;
}
else if (above < 0 && below >= 0)
{
rectAbove = midPoint;
diff = 40;
rectBelow = midPoint - heightBelow;
flag = true;
}
else if (above >= 0 && below < 0)
{
rectAbove = midPoint - heightAbove;
diff = 40;
rectBelow = midPoint;
flag = true;
}
repaint();
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(400, 400));
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawRect(0, 0, getWidth(), getHeight());
if (flag)
g.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);
makeRectangles(g);
}
private void makeRectangles(Graphics g)
{
g.setColor(Color.RED);
g.fillRect(40, rectAbove, width, heightAbove);
g.setColor(Color.BLUE);
g.fillRect(diff, rectBelow, width, heightBelow);
g.dispose();
}
}
Here is the output:
I have a gradient background and I want, slowly, for it to change colors, basically for it to go through different colors. The color has to blend through all the colors, I do not want it to flick through colors, is this possible? Please enlighten me with a solution, thanks.
Also consider java.awt.image.MemoryImageSource and a javax.swing.Timer, illustrated here and below.
Really too hard to say anything (whatever clever) to my defense, (try & enjoy)
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import javax.swing.*;
public class GradientPaintWithSwingTimerAndRunnable extends JFrame implements Runnable {
private static final long serialVersionUID = 1L;
private Queue<Icon> iconQueue = new LinkedList<Icon>();
private JLabel label = new JLabel();
private Random random = new Random();
private JPanel buttonPanel = new JPanel();
private JPanel labelPanel = new JPanel();
private Timer backTtimer;
private Timer labelTimer;
private JLabel one = new JLabel("one");
private JLabel two = new JLabel("two");
private JLabel three = new JLabel("three");
private final String[] petStrings = {"Bird", "Cat", "Dog",
"Rabbit", "Pig", "Fish", "Horse", "Cow", "Bee", "Skunk"};
private boolean runProcess = true;
private int index = 1;
private int index1 = 1;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
GradientPaintWithSwingTimerAndRunnable t = new GradientPaintWithSwingTimerAndRunnable();
}
});
}
public GradientPaintWithSwingTimerAndRunnable() {
iconQueue.add(UIManager.getIcon("OptionPane.errorIcon"));
iconQueue.add(UIManager.getIcon("OptionPane.informationIcon"));
iconQueue.add(UIManager.getIcon("OptionPane.warningIcon"));
iconQueue.add(UIManager.getIcon("OptionPane.questionIcon"));
one.setFont(new Font("Dialog", Font.BOLD, 24));
one.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
two.setFont(new Font("Dialog", Font.BOLD, 24));
two.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
three.setFont(new Font("Dialog", Font.BOLD, 10));
three.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
labelPanel.setLayout(new GridLayout(0, 3, 4, 4));
labelPanel.add(one);
labelPanel.add(two);
labelPanel.add(three);
//labelPanel.setBorder(new LineBorder(Color.black, 1));
labelPanel.setOpaque(false);
JButton button0 = createButton();
JButton button1 = createButton();
JButton button2 = createButton();
JButton button3 = createButton();
buttonPanel.setLayout(new GridLayout(0, 4, 4, 4));
buttonPanel.add(button0);
buttonPanel.add(button1);
buttonPanel.add(button2);
buttonPanel.add(button3);
//buttonPanel.setBorder(new LineBorder(Color.black, 1));
buttonPanel.setOpaque(false);
label.setLayout(new BorderLayout());
label.add(labelPanel, BorderLayout.NORTH);
label.add(buttonPanel, BorderLayout.SOUTH);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
label.setPreferredSize(new Dimension(d.width / 3, d.height / 3));
add(label, BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
startBackground();
startLabel2();
new Thread(this).start();
printWords(); // generating freeze Swing GUI durring EDT
}
private JButton createButton() {
JButton button = new JButton();
button.setBorderPainted(false);
button.setBorder(null);
button.setFocusable(false);
button.setMargin(new Insets(0, 0, 0, 0));
button.setContentAreaFilled(false);
button.setIcon(nextIcon());
button.setRolloverIcon(nextIcon());
button.setPressedIcon(nextIcon());
button.setDisabledIcon(nextIcon());
nextIcon();
return button;
}
private Icon nextIcon() {
Icon icon = iconQueue.peek();
iconQueue.add(iconQueue.remove());
return icon;
}
// Update background at 4/3 Hz
private void startBackground() {
backTtimer = new javax.swing.Timer(750, updateBackground());
backTtimer.start();
backTtimer.setRepeats(true);
}
private Action updateBackground() {
return new AbstractAction("Background action") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
label.setIcon(new ImageIcon(getImage()));
}
};
}
// Update Label two at 2 Hz
private void startLabel2() {
labelTimer = new javax.swing.Timer(500, updateLabel2());
labelTimer.start();
labelTimer.setRepeats(true);
}
private Action updateLabel2() {
return new AbstractAction("Label action") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
two.setText(petStrings[index]);
index = (index + 1) % petStrings.length;
}
};
}
// Update lable one at 3 Hz
#Override
public void run() {
while (runProcess) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
one.setText(petStrings[index1]);
index1 = (index1 + 1) % petStrings.length;
}
});
try {
Thread.sleep(300);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// Note: blocks EDT
private void printWords() {
for (int i = 0; i < petStrings.length; i++) {
String word = petStrings[i].toString();
System.out.println(word);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
three.setText(word);
}
three.setText("<html> Concurency Issues in Swing<br>"
+ " never to use Thread.sleep(int) <br>"
+ " durring EDT, simple to freeze GUI </html>");
}
public BufferedImage getImage() {
int w = label.getWidth();
int h = label.getHeight();
GradientPaint gp = new GradientPaint(0f, 0f, new Color(
127 + random.nextInt(128),
127 + random.nextInt(128),
127 + random.nextInt(128)),
w, w,
new Color(random.nextInt(128), random.nextInt(128), random.nextInt(128)));
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bi.createGraphics();
g2d.setPaint(gp);
g2d.fillRect(0, 0, w, h);
g2d.setColor(Color.BLACK);
return bi;
}
}