unable to get marquee effect [duplicate] - java

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Marquee effect in Java Swing
I am trying to obtain marquee effect (the same we have in html). But I am unable to do so with this code. How can I improve this code to obtain marquee effect?
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
class tester {
JLabel l;
tester() {
JFrame fr=new JFrame();
JPanel p=new JPanel();
l=new JLabel("");
fr.add(p);
p.add(l);
fr.setVisible(true);
fr.setSize(400,400);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void MarqueeEffect() {
ActionListener ac = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
l.setText("To action alone hast thou a right and never at all to its fruits let not the fruits of action be thy motive; neither let there be in thee any attachment to inaction");
}
};
new Timer(2000,ac).start();
}
public static void main(String args[]) {
tester t=new tester();
t.MarqueeEffect();
}
}

You will have to extend JLabel and override paintComponent to bring marquee effect. It wont come just by setting text to it without extending JLabel. You can do something like this in your customized JLabel class.
protected void paintComponent(Graphics g)
{
g.translate((int)((System.currentTimeMillis() / MARQUEE_SPEED_DIV) % (getWidth() * 2)) - getWidth(), 0);
super.paintComponent(g);
repaint(REPAINT_WITHIN_MS);
}

Related

A loop in action performed method Doesn't Working in java [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
Question: Write JFrame that when you press the "start" button draws, and keep drawing random colored and sized filled ovals until the "stop" button is pressed.
Problem: loop inside the actionPerformed method() Doesn't Work.
The Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class p6 extends JFrame implements ActionListener
{
String str;
JButton start,stop;
int h=0,w=0;
p6()
{
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(1500,1000);
start= new JButton("Start");
stop= new JButton("Stop");
setLayout(null);
start.setBounds(500, 50, 100,30);
stop.setBounds(610, 50, 100,30);
add(start);
add(stop);
start.addActionListener(this);
stop.addActionListener(this);
}
public void actionPerformed(ActionEvent ae)
{
String c=ae.getActionCommand();
if(c=="Start")
{
while(c!="Stop")
{
h+=20;
w+=20;
}
repaint();
}
str=" "+h+" "+w;
}
public void paint(Graphics g)
{
super.paintComponents(g);
g.drawString(str, 100, 100);
//g.drawOval(100, 100, 100, 100);
g.drawOval((int)Math.random()*2000,(int) Math.random()*2000, w,h);
}
public static void main(String[] args)
{
new p6();
}
}
Let's start with How do I compare strings in Java?. This is pretty basic Java 101 and something you REALLY need to understand.
The move onto Concurrency in Swing. Swing is a single threaded. This means that any long running or blocking operations executed within the context of the Event Dispatching Thread will cause the app to "hang" and prevent any further possible updates or interaction.
Swing is also not thread safe, which means that you should only ever update the UI or state the UI depends on, from within the context of the Event Dispatching Thread.
This might seem like a dilemma, but Swing also provides a useful tool to help work with these constraints, see How to user Swing Timer for more details.
Swing also has a well defined and documented painting process, see Painting in AWT and Swing and Performing Custom Painting to get a better understand of how painting works in Swing and how you're suppose to work with it
It is generally recommended not to override the paint method of top level containers (like JFrame). These tend to be composite components and trying to paint on them tends to end up not working very well.
Image from How to Use Root Panes
And you really should make the time to learn how to use layout managers, see Laying Out Components Within a Container. They will save many hours of frustration. The following examples makes use of both a BorderLayout and CardLayout.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private CardLayout cardLayout;
private JPanel showPane;
private DrawingPane drawingPane;
public TestPane() {
setLayout(new BorderLayout());
cardLayout = new CardLayout();
showPane = new JPanel(cardLayout);
showPane.add(new EmptyPane(), "Empty");
drawingPane = new DrawingPane();
showPane.add(drawingPane, "Drawing");
cardLayout.show(showPane, "Empty");
add(showPane);
JButton startButton = new JButton("Start");
JButton stopButton = new JButton("Stop");
stopButton.setEnabled(false);
JPanel actionsPane = new JPanel();
actionsPane.add(startButton);
actionsPane.add(stopButton);
add(actionsPane, BorderLayout.SOUTH);
startButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
startButton.setEnabled(false);
stopButton.setEnabled(true);
drawingPane.start();
cardLayout.show(showPane, "Drawing");
}
});
stopButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
startButton.setEnabled(true);
stopButton.setEnabled(false);
drawingPane.stop();
cardLayout.show(showPane, "Empty");
}
});
}
}
public class EmptyPane extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
public class DrawingPane extends JPanel {
private int h = 0, w = 0;
private Timer timer;
private Random rnd = new Random();
public DrawingPane() {
}
public void start() {
if (timer == null) {
timer = new Timer(500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
h += 20;
w += 20;
repaint();
}
});
}
timer.start();
}
public void stop() {
if (timer != null) {
timer.stop();
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
int x = 0;
int y = 0;
if (w < getWidth() && h < getHeight()) {
x = rnd.nextInt(0, getWidth() - w);
y = rnd.nextInt(0, getHeight() - w);
}
g2d.drawOval(x, y, w, h);
g2d.dispose();
}
}
}
Why make use of CardLayout?
Based on the original code, when not painting, nothing is shown. So I made use of a CardLayout to switch to an "empty" state. Now, it wouldn't be very hard to derive a model to hold the state information and share that between the "empty" and "running" states and show something different on the "empty" state. Equally, we could make use of the glassPane, but I think we're drifting of course.
The purpose is to demonstrate ONE possible solution for showing different states.
Why use two different panes?
First, we don't "need" EmptyPane, we could get away with just an instance of JPanel, but, if you wanted to display something else when not drawing, this is one approach you could take.
The original code had a if statement which means that when not drawing, nothing is painted, so why waste the time and instead just show a "empty" pane instead.
Again, this is just a demonstration of one possible solution.
You have to add these lines before actionPerformed method,
start.setActionCommand("start");
stop.setActionCommand("stop");

Cannot get an Oval to Display

I'm new here. Been reading questions and answers for aeons. Recently I found time to start studying Java, and I'm seriously enjoying the process. Until I started to write some code. The getting stuck is killing me. So I've come to seek advice on something extremely simple but I cannot crack it.
The code below attempts to create a frame, maximize it, and place elements inside. I was just fooling around. First the button1, I tried to change its size (so I got it into a FlowLayout). Then a button in the mainPanel, just to... try. Then an oval. I tried for 2 hours to get the oval to display but it is Impossible. When I found about "drawOval" I thought that was it but it made no difference. And to think that I was planning for the button1 to create Moving Balls. I'm so, So far away from that.
Please, why does the silly Oval refuse to display itself. Help.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MainClass {
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel();
JPanel southPanel = new JPanel();
JButton button1 = new JButton("Button1");
JButton button2 = new JButton("Button2");
Oval oval = new Oval();
public static void main(String[] args) {
MainClass program = new MainClass();
program.go();
}
public void go() {
buildGUI();
}
public void buildGUI() {
button1.setBorder(BorderFactory.createMatteBorder(2,2,2,2, Color.BLACK));
button1.addActionListener(new Button1Listener());
frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
button1.setPreferredSize(new Dimension(200, 50));
frame.getContentPane().add(BorderLayout.SOUTH, southPanel);
southPanel.add(button1);
mainPanel.add(button2);
mainPanel.add(oval);
frame.setSize(400, 400);
frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
class Button1Listener implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
//What the button will do.
}
}
}
And the Oval part
import java.awt.*;
import javax.swing.*;
public class Oval extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.orange);
g.fillOval(20, 50, 100, 100);
}
}
JPanel uses a FlowLayout by default. Since you Oval class doesn't provide any sizing hints, then it's set to a default size of 0x0.
Start by updating your class to something more like...
public class Oval extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(120, 150);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.orange);
g.fillOval(20, 50, 100, 100);
}
}
to create Moving Balls.
Ok, you might want to have a look at:
java bounceBall mouse escape
paintComponent not working

paintComponent() in Java is not being called [duplicate]

This question already has answers here:
Swing - paintComponent method not being called
(2 answers)
Closed 5 years ago.
I am trying to draw a simple rectangle but I think the paintComponent method is not getting called.
Here is the code for the class with main method:
package painting;
import java.awt.*;
import javax.swing.*;
public class Painting {
public static void main(String[] args) {
JFrame jf;
jf = new JFrame("JUST DRAW A RECTANGLE");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLayout(null);
jf.setLocationRelativeTo(null);
jf.setSize(600,600);
jf.setVisible(true);
Mainting maint = new Mainting();
jf.add(maint);
}
}
and the class with paintComponent()
package painting;
import java.awt.*;
import javax.swing.*;
public class Mainting extends JPanel {
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawRect(0, 0 , 200, 200);
System.out.println("haha");
g.setColor(Color.red);
}
}
What is the problem here, I cannot figure out...
While the answers already provided might have resulted in the rectangle appearing, the approach was less than optimal. This example aims to show a better approach. Read the comments in the code for details.
Note that Swing/AWT GUIs should be started on the EDT. This is left as an exercise for the reader.
import java.awt.*;
import javax.swing.*;
public class Painting {
public static void main(String[] args) {
JFrame jf = new JFrame("JUST DRAW A RECTANGLE");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// null layouts cause more problems than they solve. DO NOT USE!
//jf.setLayout(null);
jf.setLocationRelativeTo(null);
/* if components return a sensible preferred size,
it's better to add them, then pack */
//jf.setSize(600, 600);
//jf.setVisible(true); // as mentioned, this should be last
Mainting maint = new Mainting();
jf.add(maint);
jf.pack(); // makes the GUI the size it NEEDS to be
jf.setVisible(true);
}
}
class Mainting extends JPanel {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.drawRect(10, 10, 200, 200);
System.out.println("paintComponent called");
/* This does nothing useful, since nothing is painted
before the Graphics instance goes out of scope! */
//g.setColor(Color.red);
}
#Override
public Dimension getPreferredSize() {
// Provide hints to the layout manager!
return new Dimension(220, 220);
}
}
Try setting your layout manager to eg. BorderLayout
so use
jf.setLayout(new BorderLayout());
and then add your component with some constraints
Mainting maint = new Mainting();
jf.add(maint,BorderLayout.CENTER);

Problems with java graphics [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Can anyone give me some information what did I do wrong? Program runs but drowing a rectangle or anything else doesnt work. There is just empty space on the middle. I tried open the program from terminal and eclipse on kubuntu 15 and windows. Always with the same result.
I m just starting my adventure with java so please be patient.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyGUI {
JFrame frame;
JLabel label;
public static void main(String[] args)
{
MyGUI gui = new MyGUI();
gui.go();
}
public void go()
{
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton labelButton = new JButton("Change label");
labelButton.addActionListener(new LabelListener());
JButton colorButton = new JButton("Change color");
colorButton.addActionListener(new ColorListener());
label = new JLabel("LABEL");
DrawSmth2 drawPanel = new DrawSmth2();
frame.getContentPane().add(BorderLayout.SOUTH, colorButton);
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
frame.getContentPane().add(BorderLayout.EAST, labelButton);
frame.getContentPane().add(BorderLayout.WEST, label);
frame.setSize(680,480);
frame.setVisible(true);
}
class LabelListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
label.setText("DONE");
}
}
class ColorListener implements ActionListener
{
public void actionPerformed(ActionEvent e) {
frame.repaint();
}
}
public class DrawSmth2 extends JPanel{
public void PaintComponent(Graphics g)
{
g.setColor(Color.blue);
g.fillRect(0, 0, getWidth(), getHeight());
}
}
}
Java is case-sensitive which means that PaintComponent is not the same as paintComponent. To avoid such problems always add #Override annotation to methods you want to override (if you are not overriding existing method compiler will inform you about it - more info: When do you use Java's #Override annotation and why?).
Also don't forget to call super.paintComponent(g); at start of your own implementation of paintComponent to let Swing perform standard operations needed to properly paint this component.
Just add gloabal variable count;
int count=0;
class ColorListener implements ActionListener
{
public void actionPerformed(ActionEvent e) {
count++;
frame.repaint();
}
}
public class DrawSmth2 extends JPanel{
public void paintComponent(Graphics g)
{
if(count%2==1)
g.setColor(Color.blue);
g.fillRect(0, 0, getWidth(), getHeight());
}
}

JButton and JLabel dissappears when adding custom background

JButton and JLabel disappears when adding custom background. I don't see any problems in my program, but maybe you guys find an solution! I think it's only a little thing I forgot, but I can't figure it out.
Here's the code:
GameWindow.java:
setContentPane(new StartImagePanel(RollrackLogo));
out.println("adding JLWelcome");
JLWelcome.setText("Welcome to Rollrack, " + namewindow.name);
add(JLWelcome);
JLWelcome.setVisible(true);
out.println("JLWelcome added");
out.println("adding JBRandom");
JBRandom.setText("Random");
add(JBRandom);
JBRandom.setVisible(true);
out.println("added JBRandom");
The background appears perfect, but not the JButton and JLabel!
Code to the StartImagePanel.java:
public class StartImagePanel extends JComponent{
private Image image;
public StartImagePanel(Image image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, null);
}
}
Your button and label are added to your GameWindow frame while they should be added to its contentPane, setContentPane(new StartImagePanel(RollrackLogo)); instead. That's why they are not showing, they are added to the frame.
Make a variable of the StartImagePanel and add the button and label to it and they should show up.
StartImagePanel contentPanel = new StartImagePanel(RollrackLogo);
setContentPane(contentPanel);
...
out.println("adding JLWelcome");
JLWelcome.setText("Welcome to Rollrack, " + namewindow.name);
contentPanel.add(JLWelcome);
JLWelcome.setVisible(true);
out.println("JLWelcome added");
out.println("adding JBRandom");
JBRandom.setText("Random");
contentPanel.add(JBRandom);
JBRandom.setVisible(true);
out.println("added JBRandom");
Answer dispute
The claims in the first paragraph are plain wrong. Here is source that proves it.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class AddToCustomContentPane {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
// the GUI as seen by the user (without frame)
JPanel gui = new JPanel(new FlowLayout());
gui.setBorder(new EmptyBorder(2, 3, 2, 3));
gui.setBackground(Color.RED);
JFrame f = new JFrame("Demo");
f.setContentPane(gui);
// Acid test. Can we add buttons direct to the frame?
f.add(new JButton("Button 1"));
f.add(new JButton("Button 2"));
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
Edit after the custom panel code was given
Here's a snippet that works to show both button and label on a black image background, I removed that was not needed (listeners).
public static void main(String[] v) {
class StartImagePanel extends JPanel {
private Image image;
public StartImagePanel(Image image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, null);
}
}
class GameWindow extends JFrame{
public GameWindow() {
BufferedImage RollrackLogo;
RollrackLogo = new BufferedImage(400,200,BufferedImage.TYPE_INT_RGB);
final JButton JBRandom = new JButton();
final JLabel JLWelcome = new JLabel();
setDefaultCloseOperation(EXIT_ON_CLOSE);
StartImagePanel panel = new StartImagePanel(RollrackLogo);
setContentPane(panel);
setExtendedState(MAXIMIZED_BOTH);
setVisible(true);
JLWelcome.setText("Welcome to Rollrack");
panel.add(JLWelcome);
JLWelcome.setVisible(true);
JBRandom.setText("Random");
panel.add(JBRandom);
JBRandom.setVisible(true);
}
}
GameWindow window = new GameWindow();
window.pack();
window.setVisible(true);
}
I rather use an instance of a JFrame, instead of extending it, as #Andrew Thompson suggested in another question.
However, if you're extending it, it might be a good practice to call super() in the constructor.
Additionally, we may need to know what is going on in your StartImagePanel.
It seems, to me, to be the problem.
Ensure both your GameWindow and StartImagePanel extend properly their superclasses (call super();).
Ensure your StartImagePanel has a proper Layout.
Add your components before you set your frame visible. This also means you won't need JLWelcome.setVisible(true);.
Ensure that your code is executed in the EDT (Event-Dispatch Thread).
Example:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class GameWindow extends JFrame{
BufferedImage rollrackLogo;
JButton jbRandom;
JLabel jlWelcome;
public GameWindow() {
super();
jbRandom = new JButton("Random");
jlWelcome = new JLabel("Welcome to Rollrack, " +
namewindow.name);
rollrackLogo = new BufferedImage(400, 200,
BufferedImage.TYPE_INT_RGB);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setContentPane(new StartImagePanel(rollrackLogo));
// Add your components.
add(jlWelcome);
add(jbRandom);
addKeyListener(new KeyListener() {
#SuppressWarnings("static-access")
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == e.VK_ESCAPE){
System.exit(7);
}
}
#Override
public void keyReleased(KeyEvent arg0) {}
#Override
public void keyTyped(KeyEvent arg0) {}
});
// Pack, or otherwise set fullscreen.
pack();
// Now, set frame visible.
setVisible(true);
}
}
Edit: Now that you've posted the code for your StartImagePanel, I see that you're extending JComponent. Follow my previous advice, (call super), set a Layout, and extend JPanel instead.

Categories

Resources