My JFrame doesn't draw a string of options - java

In my game I have different states, and the first state is the Main Menu. However, it does not draw that Main Menu for an unknown reason to me.
Main-code:
package Game.Window;
import java.awt.BorderLayout;
import javax.swing.JFrame;
public class Window {
public static void main(String[] args){
JFrame frame = new JFrame("TITLE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLayout(new BorderLayout());
frame.add(new Game(), BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Game-code:
package Game.Window;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import Game.Framework.GameStateManager;
public class Game extends JPanel implements Runnable, KeyListener{
private static final long serialVersionUID = 1L;
public static final int WIDTH = 800;
public static final int HEIGHT = WIDTH/12*9;
private Thread thread;
private boolean isRunning = true;
private int FPS = 60;
private long targetTime = 1000/FPS;
private GameStateManager gsm;
public Game(){
setPreferredSize(new Dimension(WIDTH, HEIGHT));
start();
}
private void start(){
isRunning = true;
thread = new Thread(this);
thread.start();
}
public void run() {
long start, elapsed, wait;
gsm = new GameStateManager();
while(isRunning){
start = System.nanoTime();
tick();
repaint();
elapsed = System.nanoTime();
wait = targetTime - elapsed/1000000;
if(wait <= 0){
wait = 5;
}
try{
Thread.sleep(wait);
}catch(Exception e){
e.printStackTrace();
}
}
}
public void tick(){
gsm.tick();
// Shows Current FPS: System.out.println(FPS);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.clearRect(0, 0, WIDTH, WIDTH);
gsm.draw(g);
}
public void keyPressed(KeyEvent e) {
gsm.keyPressed(e.getKeyCode());
}
public void keyReleased(KeyEvent e) {
gsm.keyReleased(e.getKeyCode());
}
public void keyTyped(KeyEvent e) {
}
}
GameStateManager-code:
package Game.Framework;
import java.awt.Graphics;
import java.util.Stack;
import Game.States.MainMenu;
public class GameStateManager {
private Stack<GameState> states;
public GameStateManager(){
states = new Stack<GameState>();
states.push(new MainMenu(this));
}
public void tick(){
states.peek().tick();
}
public void draw(Graphics g){
states.peek().draw(g);
}
public void keyPressed(int k){
states.peek().keyPressed(k);
}
public void keyReleased(int k){
states.peek().keyReleased(k);
}
}
GameState-code:
package Game.Framework;
import java.awt.Graphics;
public abstract class GameState {
protected GameStateManager gsm;
public GameState(GameStateManager gsm){
this.gsm = gsm;
init();
}
public abstract void init();
public abstract void tick();
public abstract void draw(Graphics g);
public abstract void keyPressed(int k);
public abstract void keyReleased(int k);
}
And the Main Menu-code:
package Game.States;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import Game.Framework.GameState;
import Game.Framework.GameStateManager;
import Game.Window.Game;
public class MainMenu extends GameState{
private String[] options = {"New Game", "Load Game", "Options", "Exit"};
private int currentSelection = 0;
public MainMenu(GameStateManager gsm) {
super(gsm);
}
public void init() {}
public void tick() {
}
public void draw(Graphics g) {
for(int i = 0; i < options.length; i++){
if(i == currentSelection){
g.setColor(Color.GREEN);
}else{
g.setColor(Color.BLACK);
}
g.setFont(new Font("Arial", Font.PLAIN, 24));
g.drawString(options[i], Game.WIDTH/2-50, 50*i*30);
}
}
public void keyPressed(int k) {
}
public void keyReleased(int k) {
}
}
I can however draw rectangles from the Game-code, line 65.

Your math looks a little wrong.
g.drawString(options[i], Game.WIDTH/2-50, 50 * i + 30);
//add, not multiply^
A couple other things
class MainMenu extends GameState{
//declare font once
private static final Font ARIAL_24 = new Font("Arial", Font.PLAIN, 24);
private String[] options = {"New Game", "Load Game", "Options", "Exit"};
private int currentSelection = 0;
public MainMenu(GameStateManager gsm) {
super(gsm);
}
public void init() {}
public void tick() {
}
public void draw(Graphics g) {
for(int i = 0; i < options.length; i++){
//simple ternary operator can replace what was here before.
g.setColor(i == currentSelection ? Color.GREEN : Color.BLACK);
//since this never changes make it static and final
//avoid recreating objects in a paint method, or when not neccesary
g.setFont(ARIAL_24);
g.drawString(options[i], Game.WIDTH/2-50, 50 * i + 30);
}
}
public void keyPressed(int k) {
}
public void keyReleased(int k) {
}
}

I think you want to draw those strings from top to bottom,so in MainMenu-code,line 32,the value of "y" should be "50*i+30".

Related

How to fix flickering of dynamic moving images over a JPanel that is on top of another pre-painted JPanel?

I have made 2 JPanels, Panel and BackGround, in a JFrame. I am dynamically painting the Panel after 10ms(using a Timer), but the BackGround is only painted once at the beginning of the game. The Panel is responsible for the displaying of the fighters(spacecrafts), the projectiles and the aliens. The BackGround is responsible for the displaying of the background scene which is non-dynamic. The paintComponent(Graphics) method does paint the fighters and the projectiles, but flickers when they are updating. Can someone find the cause.
This is my Frame:
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Frame extends JFrame {
private static final long serialVersionUID = 1L;
public static final int WIDTH = 1280;
public static final int HEIGHT = 720;
public static final int DELAY = 10;
private Panel panel;
private Background bg;
public Frame() {
panel = new Panel();
bg = new Background();
initComponents();
}
public void initComponents() {
this.setSize(WIDTH, HEIGHT);
this.add(bg);
this.add(panel);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_LEFT) panel.moveLeft();
else if(e.getKeyCode() == KeyEvent.VK_RIGHT) panel.moveRight();
}
});
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Frame().setVisible(true);
}
});
}
}
This is my Panel:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Panel extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
public static final int DELAY = Frame.DELAY;
private Timer timer;
private BufferedImage fighter;
int x, y;
public Panel() {
timer = new Timer(DELAY, this);
try {
fighter = ImageIO.read(this.getClass().getResource("fighter.png"));
} catch (IOException e) {
e.printStackTrace();
}
initComponents();
timer.start();
}
public void initComponents() {
this.setSize(Frame.WIDTH, Frame.HEIGHT);
this.setDoubleBuffered(true);
this.setBackground(new Color(0, 0, 0, 0));
x = 150;
y = 200;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
doDrawing(g2d);
}
private void doDrawing(Graphics2D g2d) {
g2d.drawImage(fighter, x, y, null);
}
#Override
public void actionPerformed(ActionEvent arg0) {
this.repaint();
}
public void moveLeft() {
x -= 10;
}
public void moveRight() {
x += 10;
}
}
This is the BackGround:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Background extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;
private BufferedImage backGround;
private Timer timer;
public Background() {
this.setSize(Frame.WIDTH, Frame.HEIGHT);
this.setBackground(new Color(0, 0, 0, 0));
timer = new Timer(Frame.DELAY, this);
try {
backGround = ImageIO.read(this.getClass().getResource("background.png"));
} catch (IOException e) {
e.printStackTrace();
}
timer.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(backGround, 0, 0, null);
}
#Override
public void actionPerformed(ActionEvent e) {
this.repaint();
}
}
I expect the sprites not to flicker and not to lag(which is not happening after lots of trials).
Do not call repaint within a painting method
Get rid of the Background class and do all drawing in one JPanel. For example:
See example below of both as well as of MCVE design
whole thing can be copy/pasted into IDE and run
uses images available to all online, not on disk
I would also remove the Timer that simply calls repaint() and instead either
call repaint from within the KeyListener
or use the timer to do the actual sprite movement code (with repaint()). This would be useful if you want continuous movement
Example MCVE:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Frame1 extends JFrame {
// Image attribution:
// By Adam Evans - M31, the Andromeda Galaxy (now with h-alpha)
// Uploaded by NotFromUtrecht, CC BY 2.0,
// https://commons.wikimedia.org/w/index.php?curid=12654493
public static final String ANDROMEDA_IMAGE = "https://upload.wikimedia.org/wikipedia/commons/"
+ "thumb/9/98/Andromeda_Galaxy_%28with_h-alpha%29.jpg/"
+ "1280px-Andromeda_Galaxy_%28with_h-alpha%29.jpg";
public static final String SPRITE_IMAGE = "https://upload.wikimedia.org/wikipedia/commons/"
+ "thumb/a/a1/Glossy_3d_blue_blue2.png/" + "120px-Glossy_3d_blue_blue2.png";
private static final long serialVersionUID = 1L;
public static final int WIDTH = 1280;
public static final int HEIGHT = 720;
public static final int DELAY = 10;
private Panel1 panel;
// private Background bg;
public Frame1() {
panel = new Panel1();
// bg = new Background();
initComponents();
}
public void initComponents() {
this.setSize(WIDTH, HEIGHT);
// this.add(bg);
this.add(panel);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT)
panel.moveLeft();
else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
panel.moveRight();
}
});
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Frame1().setVisible(true);
}
});
}
}
class Panel1 extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
public static final int DELAY = Frame1.DELAY;
private Timer timer;
private BufferedImage fighter;
private BufferedImage background;
int x, y;
public Panel1() {
timer = new Timer(DELAY, this);
try {
URL url = new URL(Frame1.SPRITE_IMAGE);
// fighter = ImageIO.read(this.getClass().getResource("fighter.png"));
fighter = ImageIO.read(url);
url = new URL(Frame1.ANDROMEDA_IMAGE);
background = ImageIO.read(url);
} catch (IOException e) {
e.printStackTrace();
}
initComponents();
timer.start();
}
public void initComponents() {
this.setSize(Frame1.WIDTH, Frame1.HEIGHT);
this.setDoubleBuffered(true);
this.setBackground(new Color(0, 0, 0, 0));
x = 150;
y = 200;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(background, 0, 0, this);
g.drawImage(fighter, x, y, this);
}
#Override
public void actionPerformed(ActionEvent arg0) {
this.repaint();
}
public void moveLeft() {
x -= 10;
}
public void moveRight() {
x += 10;
}
}

how do I make this java awt/ swing animation work?

I'm pretty new to java coding, but i know the basic structures of how to code. I am not familiar with awt/swing, and don't know what my error is.
Background: I searched up ways to animate with java, found zetcode tutorials.
I copy/pasted their code, and tested the program, to make sure it works. the JFrame opened, but nothing drew. Maybe this is a system compatibility error? if so, how would I fix it?
these are the two separate classes:
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.JFrame;
public class ThreadAnimationExample extends JFrame {
public ThreadAnimationExample() {
initUI();
}
private void initUI() {
add(new Board());
setResizable(false);
pack();
setTitle("Star");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame ex = new ThreadAnimationExample();
ex.setVisible(true);
}
});
}
}
This is the main class.
Board.java
package com.zetcode;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class Board extends JPanel
implements Runnable {
private final int B_WIDTH = 350;
private final int B_HEIGHT = 350;
private final int INITIAL_X = -40;
private final int INITIAL_Y = -40;
private final int DELAY = 25;
private Image star;
private Thread animator;
private int x, y;
public Board() {
initBoard();
}
private void loadImage() {
ImageIcon ii = new ImageIcon("star.png");
star = ii.getImage();
}
private void initBoard() {
setBackground(Color.BLACK);
setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
setDoubleBuffered(true);
loadImage();
x = INITIAL_X;
y = INITIAL_Y;
}
#Override
public void addNotify() {
super.addNotify();
animator = new Thread(this);
animator.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
drawStar(g);
}
private void drawStar(Graphics g) {
g.drawImage(star, x, y, this);
Toolkit.getDefaultToolkit().sync();
}
private void cycle() {
x += 1;
y += 1;
if (y > B_HEIGHT) {
y = INITIAL_Y;
x = INITIAL_X;
}
}
#Override
public void run() {
long beforeTime, timeDiff, sleep;
beforeTime = System.currentTimeMillis();
while (true) {
cycle();
repaint();
timeDiff = System.currentTimeMillis() - beforeTime;
sleep = DELAY - timeDiff;
if (sleep < 0) {
sleep = 2;
}
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
System.out.println("Interrupted: " + e.getMessage());
}
beforeTime = System.currentTimeMillis();
}
}
}
When I run the program, I get a blank black window. The program is supposed to draw a star. Here is what it is supposed to look like.

java graphics isn't drawing anything

The program draws a bunch of rectangles for a bar graph. I know the bar class works perfectly fine because I've got it working before adding in the graph panel class. I was drawing straight onto the frame instead of the graph panel. I assume its a problem in the way my set visible methods are called as it was pointed out to me before. I tried looking into it but I've had no luck after playing around and reading documentation.
import java.awt.Color;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.concurrent.Semaphore;
#SuppressWarnings("serial")
public class GraphPanel extends JPanel {
private ArrayList<Bar> graphBars;
private int nBars;
public GraphPanel(int nBars, JFrame mainFrame) {
this.setSize(400, 400);
this.graphBars = new ArrayList<Bar>(nBars);
this.nBars = nBars;
this.initBars(mainFrame.getWidth());
for(Bar b: this.graphBars) {
this.add(b);
}
}
private void initBars(int frameW) {
Random random = new Random();
float hue;
Color color;
int barPadding = frameW/this.nBars;
for(int i = 0; i < this.nBars; i++) {
hue = random.nextFloat();
color = Color.getHSBColor(hue, 0.9f, 1.0f);
this.graphBars.add(new Bar(i*barPadding + 30, 350, color));
}
}
public ArrayList<Bar> getBarList() {
return this.graphBars;
}
}
#SuppressWarnings("serial")
public class Bar extends JPanel implements Runnable {
int height = 0;
Color barColor;
Rectangle bar;
private final int WIDTH = 20;
Thread bartender;
private Semaphore s;
public Bar(int x, int y, Color barColor) {
this.barColor= barColor;
this.bar = new Rectangle(x, y, this.WIDTH, this.height);
this.bartender= new Thread(this);
this.s = new Semaphore(1);
}
public boolean setNewHeight(int h) {
try {
this.s.acquire();
this.height = h;
this.s.release();
return true;
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
#SuppressWarnings("deprecation")
public void update() {
if (this.bar.height < this.height) {
bar.reshape(this.bar.x, --this.bar.y, this.bar.width, ++this.bar.height);
} else {
bar.reshape(this.bar.x, ++this.bar.y, this.bar.width, --this.bar.height);
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(this.barColor);
g2d.fill(this.bar);
}
#SuppressWarnings("deprecation")
public void callBarTender() {
this.bartender.resume();
}
#SuppressWarnings("deprecation")
#Override
public void run() {
System.out.println("sdf");
while(true) {
if (this.bar.height < this.height) {
for(int i = this.bar.height; i<this.height; i++ ) {
try {
update();
repaint();
Thread.sleep(15);
} catch(Exception e) {
System.out.println(e);
}
}
} else if (this.height < this.bar.height) {
for(int i = this.bar.height; i>this.height; i-- ) {
try {
update();
repaint();
Thread.sleep(15);
} catch(Exception e) {
System.out.println(e);
}
}
}
this.bartender.suspend();
}
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(400, 400);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GraphPanel gPane = new GraphPanel(3, frame);
frame.add(gPane);
gPane.getBarList().get(0).setVisible(true);
gPane.getBarList().get(1).setVisible(true);
gPane.getBarList().get(2).setVisible(true);
gPane.setVisible(true);
frame.setVisible(true);
gPane.getBarList().get(0).setNewHeight(100);
gPane.getBarList().get(1).setNewHeight(100);
gPane.getBarList().get(2).setNewHeight(100);
gPane.getBarList().get(0).bartender.start();
gPane.getBarList().get(1).bartender.start();
gPane.getBarList().get(2).bartender.start();
}
You should override getPreferredSize of your GraphPanel to ensure that they are laid out correctly
The x/y positions you are passing to the Bar class are irrelevant, as this is causing your Rectangle to paint outside of the visible context of the Bar pane. Painting is done from within the context of the component (0x0 been the top/left corner of the component)
The use of Rectangle or the way you are using it, is actually causing issues. It's impossible to know exactly how big you component will be until it's layed or painted
There is a reason why resume and suspend are deprecated, this could cause no end of "weird" (and wonderful) issues
Take a look at Laying Out Components Within a Container for why you're bars aren't been updated correctly and why the x/y coordinates are pointless
Take a look at How to use Swing Timers for an alternative to your use of Thread
Possibly, something more like...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame();
frame.setSize(400, 400);
// frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GraphPanel gPane = new GraphPanel(3, frame);
frame.add(gPane);
gPane.getBarList().get(1).setFill(false);
gPane.getBarList().get(0).start();
gPane.getBarList().get(1).start();
gPane.getBarList().get(2).start();
frame.setVisible(true);
}
});
}
public class GraphPanel extends JPanel {
private ArrayList<Bar> graphBars;
private int nBars;
public GraphPanel(int nBars, JFrame mainFrame) {
this.graphBars = new ArrayList<Bar>(nBars);
this.nBars = nBars;
this.initBars(mainFrame.getWidth());
for (Bar b : this.graphBars) {
this.add(b);
}
}
private void initBars(int frameW) {
Random random = new Random();
float hue;
Color color;
for (int i = 0; i < this.nBars; i++) {
hue = random.nextFloat();
color = Color.getHSBColor(hue, 0.9f, 1.0f);
this.graphBars.add(new Bar(color));
}
}
public ArrayList<Bar> getBarList() {
return this.graphBars;
}
}
#SuppressWarnings("serial")
public class Bar extends JPanel {
private Color barColor;
private boolean fill = true;
private float fillAmount = 0;
private float delta = 0.01f;
private Timer timer;
private Rectangle bar;
public Bar(Color barColor) {
bar = new Rectangle();
setBorder(new LineBorder(Color.RED));
this.barColor = barColor;
timer = new Timer(15, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fillAmount += isFill() ? delta : -delta;
// System.out.println(fillAmount);
if (fillAmount < 0) {
fillAmount = 0;
((Timer) e.getSource()).stop();
} else if (fillAmount > 1.0f) {
fillAmount = 1f;
((Timer) e.getSource()).stop();
}
repaint();
}
});
}
public void start() {
timer.start();
}
public void stop() {
timer.stop();
}
public void setFill(boolean fill) {
this.fill = fill;
if (!timer.isRunning()) {
if (fill && fillAmount == 1) {
fillAmount = 0;
} else if (!fill && fillAmount == 0) {
fillAmount = 1;
}
}
}
public boolean isFill() {
return fill;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(20, 100);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(this.barColor);
int height = Math.round(getHeight() * fillAmount);
bar.setSize(getWidth(), height);
bar.setLocation(0, getHeight() - height);
g2d.fill(bar);
g2d.dispose();
}
}
}

draw a circle when certain condition is met

My program is to convert the letters to some signals.My main method generates some random letters. The letter is passed to another method which calls repaint() method based on the Letter generated.The PaintComponent() method is used to drew a circle filled with white color.When i execute the program i get only a Jframe. I don't see the circle.Please help.
package morsecode;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;
import java.awt.*;
public class MorseCode extends Frame {
public static void main(String[] args) {
MorseCode mc = new MorseCode();
MorseCode frame = new MorseCode();
final String chars = "abcdefghijklmnopqrstuvwxyz1234567890";
char word;
for(int i=1;i<=1;i++)
{
Random rand = new Random();
int x = rand.nextInt(36);
word = chars.charAt(x);
System.out.print(word);
frame.setBackground(Color.BLACK);
frame.addWindowListener(
new WindowAdapter()
{
#Override
public void windowClosing(WindowEvent we)
{
System.exit(0);
}
}
);
frame.setSize(400, 400);
frame.setVisible(true);
mc.toMorseCode(word);
}
}
void toMorseCode(char letter)
{
switch(letter)
{
case 'A' | 'a':
repaint();
Thread.sleep(1000);
repaint();
Thread.sleep(2000);
break;
case 'B' | 'b':
repaint();
Thread.sleep(1000);
repaint();
Thread.sleep(1000);
repaint();
Thread.sleep(1000);
repaint();
Thread.sleep(2000);
break; ..............
}
}
public void paintComponent(Graphics g) {
Graphics2D ga = (Graphics2D)g;
ga.setColor(Color.white);
ga.fillOval(125,125,150,150);
}
}
Two things...
First, calling Thread.sleep(2000); within the Event Dispatching Thread will prevent the EDT from processing events on the event queue, including paint events.
Second, Frame doesn't have a paintComponent.
Adding the #Override annotation and trying to call super.paintComponent would have highlighted this issue as the code wouldn't have compiled.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
First of all, start by using a JPanel to hold your core logic and perform your custom painting.
Second, use a javax.swing.Timer to perform animation. See How to use Swing Timers for more details
Updated
The basic concept is relatively simple. You need some kind of second/background thread which can generate the delays between the changes in the output. You then need to update the UI before each delay based on what type of information you are trying to display.
The implementation becomes tricky because Swing, like most GUI frameworks, is single threaded and not thread safe.
This means, you can not block the GUI thread, doing so will prevent the UI from been repainted, amongst other things and you must update the state of any UI component from within the context of the GUI thread.
This means that while you can use a Thread to run in the background, you must ensure that all changes/modifications to the UI are carried out only from within the EDT.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MorseCodeTest {
public static void main(String[] args) {
new MorseCodeTest();
}
public MorseCodeTest() {
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.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static final int GAP = 500;
public static final int DOT = 1000;
public static final int DASH = 4000;
public interface Transmitter {
public void setTap(boolean tap);
}
public class TestPane extends JPanel implements Transmitter {
private MorseCode code;
private boolean tapped;
public TestPane() {
code = MorseCode.create('A').addDot().addDash();
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
Signalar signalar = new Signalar(TestPane.this, code);
signalar.execute();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (tapped) {
Graphics2D g2d = (Graphics2D) g.create();
int diameter = Math.min(getWidth(), getHeight()) / 2;
int x = (getWidth() - diameter) / 2;
int y = (getHeight() - diameter) / 2;
g2d.fillOval(x, y, diameter, diameter);
g2d.dispose();
}
}
#Override
public void setTap(boolean tap) {
tapped = tap;
repaint();
}
}
public class Signalar extends SwingWorker<Void, Boolean> {
private final MorseCode code;
private final Transmitter transmitter;
public Signalar(Transmitter transmitter, MorseCode code) {
this.code = code;
this.transmitter = transmitter;
}
#Override
protected void process(List<Boolean> chunks) {
transmitter.setTap(chunks.get(chunks.size() - 1));
}
#Override
protected Void doInBackground() throws Exception {
for (Tone tone : code.getTones()) {
publish(true);
Thread.sleep(tone.getDelay());
publish(false);
Thread.sleep(GAP);
}
return null;
}
}
public static class Tone {
private final int delay;
public Tone(int delay) {
this.delay = delay;
}
public int getDelay() {
return delay;
}
}
public static class DashTone extends Tone {
public DashTone() {
super(DASH);
}
}
public static class DotTone extends Tone {
public DotTone() {
super(DOT);
}
}
public static class MorseCode {
private final char value;
private final List<Tone> tones;
public static MorseCode create(char value) {
MorseCode code = new MorseCode(value);
return code;
}
public MorseCode(char value) {
this.value = value;
this.tones = new ArrayList<>(25);
}
public char getValue() {
return value;
}
public MorseCode addDash() {
return addTone(new DashTone());
}
public MorseCode addDot() {
return addTone(new DotTone());
}
public MorseCode addTone(Tone tone) {
tones.add(tone);
return this;
}
public Iterable<Tone> getTones() {
return tones;
}
}
}

How can I make this JButton visible? When I have progressive scan background JWindow()?

How can I make the JButton visible?
1) When no progressive background is turned on: JButton is showing
2) When no progressive background is turned on, JButton is pressed still showing no flicker:
3) When progressive background is turned on, JButton is invisible and on pressing in this I see flicker and JButton() appears and again hides auto. << Problem is here, so how can I fix it?
import java.awt.Color;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Graphics;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
public class ButtonTest extends JWindow implements MouseListener, MouseMotionListener {
private static final long serialVersionUID = 1L;
private JFrame frame = new JFrame();
private SoftJButton softButton1;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ButtonTest j = new ButtonTest();
j.createAndShowGUI();
}
});
}
public void createAndShowGUI() {
softButton1 = new SoftJButton("Transparent Button");
softButton1.setBackground(Color.GREEN);
softButton1.setAlpha(0.5f);
softButton1.setDoubleBuffered(true);
this.setLayout(new BorderLayout());
this.setBounds(100, 30, 200, 100);
this.setBackground(new Color(0, 0, 0, 255));
this.setVisible(true);
add(softButton1);
}
#Override
public void paint(Graphics g) {
super.paint(g);
}
public void mouseDragged(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public static class SoftJButton extends JButton {
private static final JButton lafDeterminer = new JButton();
private static final long serialVersionUID = 1L;
private boolean rectangularLAF;
private float alpha = 1f;
public SoftJButton() {
this(null, null);
}
public SoftJButton(String text) {
this(text, null);
}
public SoftJButton(String text, Icon icon) {
super(text, icon);
setOpaque(false);
setFocusPainted(false);
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
repaint();
}
#Override
public void paintComponent(java.awt.Graphics g) {
java.awt.Graphics2D g2 = (java.awt.Graphics2D) g;
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
if (rectangularLAF && isBackgroundSet()) {
Color c = getBackground();
g2.setColor(c);
g.fillRect(0, 0, getWidth(), getHeight());
}
super.paintComponent(g2);
}
#Override
public void updateUI() {
super.updateUI();
lafDeterminer.updateUI();
rectangularLAF = lafDeterminer.isOpaque();
}
}
}
It's not clear how your video source works, but it appears to be incompatible with Swing due to Mixing Heavyweight and Lightweight Components. Although awt components aren't transparent, you can always draw your own translucent text on the Frame and do manual hit testing, as suggested below. You might also check to see if your video source API supports Double Buffering and Page Flipping.
import java.awt.Color;
import java.awt.AlphaComposite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Rectangle2D;
/** #see http://stackoverflow.com/questions/6725618 */
public class AlphaFrame extends Frame {
private static final Font font = new Font("Dialog", Font.BOLD, 24);
private float alpha = 1f;
private Rectangle rect = new Rectangle();
public static void main(String[] args) {
AlphaFrame af = new AlphaFrame();
af.setTitle("Translucent Button");
af.setAlpha(0.5f);
af.setForeground(Color.green);
af.setBackground(Color.black);
af.setVisible(true);
}
public AlphaFrame() {
this.setSize(320, 240);
this.setLocationRelativeTo(null);
this.setBackground(Color.white);
this.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
if (rect.contains(e.getPoint())) {
System.out.println("Pressed.");
}
}
});
repaint();
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, alpha));
g2.setColor(getForeground());
g2.setFont(font);
FontMetrics fm = g2.getFontMetrics();
String s = getTitle();
Insets i = getInsets();
int dx = i.left + 10;
int dy = i.top + fm.getHeight() + 10;
Rectangle2D bounds = fm.getStringBounds(s, g);
rect.x = dx + (int) bounds.getX() - 1;
rect.y = dy + (int) bounds.getY() - 1;
rect.width = (int) bounds.getWidth() + 1;
rect.height = (int) bounds.getHeight() + 1;
System.out.println(i + " \n" + bounds + "\n" + rect);
g2.drawRect(rect.x, rect.y, rect.width, rect.height);
g2.drawString(s, dx, dy);
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
}
}
import java.awt.event.*;
import java.awt.Color;
import java.awt.AlphaComposite;
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
public class ButtonTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ButtonTest().createAndShowGUI();
}
});
}
private JFrame frame;
private SoftJButton softButton1;
public void createAndShowGUI() {
softButton1 = new SoftJButton("Transparent Button");
softButton1.setPreferredSize(new Dimension(800, 600));
frame = new JFrame();
frame.add(softButton1);
frame.setLocation(150, 150);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
Timer alphaChanger = new Timer(30, new ActionListener() {
private float incrementer = -.03f;
#Override
public void actionPerformed(ActionEvent e) {
float newAlpha = softButton1.getAlpha() + incrementer;
if (newAlpha < 0) {
newAlpha = 0;
incrementer = -incrementer;
} else if (newAlpha > 1f) {
newAlpha = 1f;
incrementer = -incrementer;
}
softButton1.setAlpha(newAlpha);
}
});
alphaChanger.start();
Timer uiChanger = new Timer(5500, new ActionListener() {
private LookAndFeelInfo[] laf = UIManager.getInstalledLookAndFeels();
private int index = 1;
#Override
public void actionPerformed(ActionEvent e) {
try {
UIManager.setLookAndFeel(laf[index].getClassName());
SwingUtilities.updateComponentTreeUI(frame);
} catch (Exception exc) {
exc.printStackTrace();
}
index = (index + 1) % laf.length;
}
});
uiChanger.start();
}
public static class SoftJButton extends JButton {
private static final JButton lafDeterminer = new JButton();
private static final long serialVersionUID = 1L;
private boolean rectangularLAF;
private float alpha = 1f;
public SoftJButton() {
this(null, null);
}
public SoftJButton(String text) {
this(text, null);
}
public SoftJButton(String text, Icon icon) {
super(text, icon);
setOpaque(false);
setFocusPainted(false);
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
repaint();
}
#Override
public void paintComponent(java.awt.Graphics g) {
java.awt.Graphics2D g2 = (java.awt.Graphics2D) g;
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
if (rectangularLAF && isBackgroundSet()) {
Color c = getBackground();
g2.setColor(c);
g.fillRect(0, 0, getWidth(), getHeight());
}
super.paintComponent(g2);
}
#Override
public void updateUI() {
super.updateUI();
lafDeterminer.updateUI();
rectangularLAF = lafDeterminer.isOpaque();
}
}
}

Categories