This is my first time trying to build a GUI and I've reached an impasse which I can't seem to find the solution to. Currently I have parts of my GUI set up but I want to insert a graph I've created on another class, however, I'm not sure how to link it with my current JFrame. I can get it to work as a separate entity, but not together.
MainDisplay Class:
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
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(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MainDisplay().setVisible(true);
}
});
float LvBTC;
float LvLTC;
float LvETH;
float[] HBTC;
float[] HLTC;
float[] HETH;
float CurETH;
float CurBTC;
float CurLTC;
WebScraper WS1 = new WebScraper();
LvBTC = WS1.LvScrapeBTC();
LvLTC = WS1.LvScrapeLTC();
LvETH = WS1.LvScrapeETH();
HBTC = WS1.HScrapeBTC();
HLTC = WS1.HScrapeLTC();
HETH = WS1.HScrapeETH();
System.out.println("Bitcoin's Current Price is: $"+LvBTC);
System.out.println("Litecoin's Current Price is: $"+LvLTC);
System.out.println("Ethereum's Current Price is: $"+LvETH);
Graph G1 = new Graph();
G1.CurrentValues(HBTC);
for (int i = 0; 5 > i;) {
System.out.println("Day " + (i + 1) + ": $" + G1.CurValues[i]);
i++;
}
System.out.println("Index of largest value: " + G1.IndexLarge(G1.CurValues));
System.out.println("Index of smallest value: " + G1.IndexSmall(G1.CurValues));
Graph Graphing = new Graph();
}
Graph Class:
package comsci_ia;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Arrays;
import javax.swing.JFrame;
public class Graph extends JFrame {
int IndexL;
int IndexS;
int DistanceDay1;
int DistanceDay2;
int DistanceDay3;
int DistanceDay4;
int DistanceDay5;
float[] CurValues = new float[5];
ArrayList<Point> points = new ArrayList<>();
public float[] CurrentValues(float[] array) {
DatabaseBrowser DB1 = new DatabaseBrowser();
WebScraper WS1 = new WebScraper();
float[] HBTC = WS1.HScrapeBTC();
float[] HETH = WS1.HScrapeETH();
float[] HLTC = WS1.HScrapeLTC();
float CurHold = 0;
boolean BTCCheck = false;
BTCCheck = Arrays.equals(HBTC, array);
boolean LTCCheck = false;
LTCCheck = Arrays.equals(HLTC, array);
boolean ETHCheck = false;
ETHCheck = Arrays.equals(HETH, array);
if (BTCCheck == true) {
CurHold = DB1.RetriveBTC();
}
if (LTCCheck == true) {
CurHold = DB1.RetriveLTC();
}
if (ETHCheck == true) {
CurHold = DB1.RetriveETH();
}
float pick;
for (int i = 0; 5 > i;) {
for (int z = 0; z < array.length; z++) {
pick = array[z];
pick = pick * CurHold;
CurValues[i] = pick;
i++;
}
}
return CurValues;
}
public int IndexLarge(float[] array) {
float temp = 0;
for (int i = 0; 5 > i;) { //Cycles through ArrayList and replaces temp with the Largest value
if (array[i] > temp) {
temp = array[i];
}
i++;
}
int IndexCheck = 0; //Searches and records the index of "temp" value (Largest value in array)
for (IndexCheck = 0; 5 > IndexCheck;) {
if (array[IndexCheck] == temp) {
break;
}
IndexCheck++;
}
IndexL = IndexCheck;
return IndexL;
}
public int IndexSmall(float[] array) {
float temp = 1000000;
for (int i = 0; 5 > i;) { //Cycles through ArrayList and replaces temp with the smallest value
if (array[i] < temp) {
temp = array[i];
}
i++;
}
int IndexCheck = 0; //Searches and records the index of "temp" value (smallest value in array)
for (IndexCheck = 0; 5 > IndexCheck;) {
if (array[IndexCheck] == temp) {
break;
}
IndexCheck++;
}
IndexS = IndexCheck;
return IndexS;
}
public void Plotter(float[] array) {
/* int DayRefL = IndexL + 1;
int DayRefS = IndexS + 1; */
float ValRange;
float ValPx;
points = null;
ValRange = array[IndexL] - array[IndexS];
ValPx = (300f/ ValRange); //Number is the pixel distance between highest and lowest values
DistanceDay1 = (int) ((int) 50 + ((array[IndexL] - array[0]) * ValPx));
DistanceDay2 = (int) ((int) 50 + ((array[IndexL] - array[1]) * ValPx));
DistanceDay3 = (int) ((int) 50 + ((array[IndexL] - array[2]) * ValPx));
DistanceDay4 = (int) ((int) 50 + ((array[IndexL] - array[3]) * ValPx));
DistanceDay5 = (int) ((int) 50 + ((array[IndexL] - array[4]) * ValPx));
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
int DotSize = 10;
int width = g2.getFontMetrics().stringWidth("Today");
int middle = width / 2;
g2.setColor(Color.BLACK);
/* g2.drawLine(10, 10, 10, 410); //Frame Boundaries
g2.drawLine(410, 10, 10, 10); //Frame Boundaries
g2.drawLine(410, 10, 410, 410); //Frame Boundaries
g2.drawLine(410, 410, 10, 410); //Frame Boundaries */
//Axis
g2.drawLine(30, 30, 30, 370);
g2.drawLine(370, 370, 30, 370);
//Points & Connections
PlotPoints(g2, 98, DistanceDay1, DotSize);
g2.drawLine(98, DistanceDay1, 166, DistanceDay2);
PlotPoints(g2, 166, DistanceDay2, DotSize);
g2.drawLine(166, DistanceDay2, 234, DistanceDay3);
PlotPoints(g2, 234, DistanceDay3, DotSize);
g2.drawLine(234, DistanceDay3, 302, DistanceDay4);
PlotPoints(g2, 302, DistanceDay4, DotSize);
g2.drawLine(302, DistanceDay4, 370, DistanceDay5);
PlotPoints(g2, 370, DistanceDay5, DotSize);
//Labels
g2.drawString("Today", 370 - middle, 390);
/* g2.drawString("Test", 98 - middle, 40);
g2.drawString("Test", 146, 25); */
}
private void PlotPoints(Graphics2D g, int x, int y, int r) {
x = x - (r / 2);
y = y - (r / 2);
g.fillOval(x, y, r, r);
}
}
If I run the Graph class as a separate entity it'll result in this: Graph pop-up
Here's a separate version of the Graph code in which a frame will pop up displaying the graph:
package graphing;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Graphing extends JPanel {
#Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
int DotSize = 10;
int width = g2.getFontMetrics().stringWidth("Test");
int middle = width / 2;
g2.setColor(Color.BLACK);
g2.drawLine(10, 10, 10, 390); //Frame Boundaries
g2.drawLine(390, 10, 10, 10); //Frame Boundaries
g2.drawLine(390, 10, 390, 390); //Frame Boundaries
g2.drawLine(390, 390, 10, 390); //Frame Boundaries
//Axis
g2.drawLine(30, 30, 30, 370);
g2.drawLine(370, 370, 30, 370);
//Points & Connections
PlotPoints(g2, 98, 55, DotSize);
g2.drawLine(98, 55, 166, 40);
PlotPoints(g2, 166, 40, DotSize);
g2.drawLine(166, 40, 234, 100);
PlotPoints(g2, 234, 100, DotSize);
g2.drawLine(234, 100, 302, 332);
PlotPoints(g2, 302, 332, DotSize);
g2.drawLine(302, 332, 370, 40);
PlotPoints(g2, 370, 40, DotSize);
//Labels
g2.drawString("Test", 98 - middle, 40);
g2.drawString("Test", 146, 25);
}
private void PlotPoints(Graphics2D g, int x, int y, int r) {
x = x - (r / 2);
y = y - (r / 2);
g.fillOval(x, y, r, r);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(420, 420);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Graphing app = new Graphing();
frame.setContentPane(app);
frame.setVisible(true);
frame.invalidate();
}
}
So, my immediate issue is, you're extending from JFrame, which isn't a good, as this locks the UI into in a single use case (it's not easily re-usable)
My second issue is, you've created a method called paintComponent in JFrame, but since JFrame doesn't use this style of painting, it is never called
So, the first thing I would do is change Graph so it extends from JPanel instead...
public class Graph extends JPanel {
//...
I would then update your paintComponent so it supports the painting process properly...
#Overrride
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
//...
Now, the next problem is, you're going to need to provide some sizing hints so that the layout manager of the container you add it to has some idea about how best to layout the component...
#Override
public Dimension getPreferredSize() {
// I've not been through your code in detail
// so I've not calculated what the actual
// preferred size might be and this is just an
// example you'll have to update
return new Dimension(200, 200);
}
Now, you can create an instance of Graph and add it to what ever container you want
Related
I had a task to draw checkers board. Here is my frame class
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JTabbedPane;
public class AppFrame extends JFrame {
public AppFrame() {
setTitle("Kółko i kwadracik");
setSize(1000, 1500);
setLocationRelativeTo(null);
initGUI();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void initGUI() {
setLayout(new BorderLayout());
JTabbedPane tabPane = new JTabbedPane();
tabPane.addTab("Plansza", new PlanszaGry());
tabPane.addTab("Obrazek", new PanelZObrazkiem());
tabPane.addTab("Wykres", new Wykres());
tabPane.addTab("Warcaby", new Warcaby());
tabPane.addTab("4 Warcaby", new Warcaby4());
add(tabPane, BorderLayout.CENTER);
}
}
Than a class to create single checkers board, it's the one new Warcaby()
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import javax.swing.JPanel;
public class Warcaby extends JPanel {
public void paint(Graphics g) {
super.paint(g);
setBackground(Color.WHITE);
Graphics2D g2 = (Graphics2D) g;
Stroke defaultStroke = g2.getStroke();
int y = 9; // tu ustawiamy liczbę linii (czyli w sumie wilekość planszy)
// linie planszy do gry
for (int i = 0; i <= y; i++) {
float dash[] = { 10.0f };
Stroke lineStroke = new BasicStroke(3.0f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER);
g2.setStroke(lineStroke);
g2.setColor(Color.BLACK);
int x = i * 100;
g2.draw(new Line2D.Double(100 + x, 100, 100 + x, 100 * y));// linie
// pionowe
g2.draw(new Line2D.Double(100, 100 + x, 100 * y, 100 + x)); // linie
// poziome
}
// Plansza do gry (czarne/białe pola)
for (int a = 1; a < y; a++) {
if (a % 2 != 0) {
for (int b = 1; b < y; b++) {
if (b % 2 == 0) {
g.setColor(Color.black);
g.fillRect(b * 100, a * 100, 100, 100);
}
}
} else {
for (int b = 1; b < y; b++) {
if (b % 2 != 0) {
g.setColor(Color.black);
g.fillRect(b * 100, a * 100, 100, 100);
}
}
}
}
}
}
My next task is to draw 4 boards next to eachother, teacher gave me a hint to create method drawing one board with information about it's position. I can't figure it out how to even start. I've start with this:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import javax.swing.JPanel;
public class Warcaby4 extends JPanel {
public void Warcaby(Graphics g, int x, int y) {
super.paint(g);
setBackground(Color.WHITE);
Graphics2D g2 = (Graphics2D) g;
Stroke defaultStroke = g2.getStroke();
float dash[] = { 10.0f };
Stroke lineStroke = new BasicStroke(3.0f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER);
g2.setStroke(lineStroke);
g2.setColor(Color.BLACK);
for (int i = 0; i <= y; i++) {
x = i * 100;
g2.draw(new Line2D.Double(100 + x, 100, 100 + x, 100 * y));// linie
// pionowe
g2.draw(new Line2D.Double(100, 100 + x, 100 * y, 100 + y)); // linie
// poziome
}
// Plansza do gry (czarne/białe pola)
for (int a = 1; a < y; a++) {
if (a % 2 != 0) {
for (int b = 1; b < y; b++) {
if (b % 2 == 0) {
g.setColor(Color.black);
g.fillRect(b * 100, a * 100, 100, 100);
}
}
} else {
for (int b = 1; b < y; b++) {
if (b % 2 != 0) {
g.setColor(Color.black);
g.fillRect(b * 100, a * 100, 100, 100);
}
}
}
}
}
}
Now I don't know where and how call out it 4 times, am I even doing it right? Please give me some suggestions. :)
My next task is to draw 4 boards next to eachother, teacher gave me a hint to create method drawing one board with information about it's position. I can't figure it out how to even start. I've start with this:
Why not just re-use the component you already have? For example, using a GridLayout you could just create as many components as you need...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class AppFrame {
public static void main(String[] args) {
new AppFrame();
}
public AppFrame() {
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("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(2, 2));
frame.add(new Warcaby());
frame.add(new Warcaby());
frame.add(new Warcaby());
frame.add(new Warcaby());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class Warcaby extends JPanel {
public Warcaby() {
setBackground(Color.WHITE);
setBorder(new EmptyBorder(5, 5, 5, 5));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// setBackground(Color.WHITE);
Graphics2D g2 = (Graphics2D) g;
Insets insets = getInsets();
int horontialPadding = insets.left + insets.right;
int verticalPadding = insets.top + insets.bottom;
int width = getWidth() - horontialPadding;
int height = getHeight() - verticalPadding;
int size = Math.min(width, height) / 10;
int xOffset = insets.left + ((width - (size * 10)) / 2);
int yOffset = insets.top + ((height - (size * 10)) / 2);
for (int vertical = 0; vertical < 10; vertical++) {
for (int horzontial = 0; horzontial < 10; horzontial++) {
int x = horzontial * size;
int y = vertical * size;
g2.setColor(Color.WHITE);
if (vertical % 2 == 0) {
if (horzontial % 2 == 0) {
g2.setColor(Color.BLACK);
}
} else if (horzontial % 2 != 0) {
g2.setColor(Color.BLACK);
}
g2.fillRect(xOffset + x, yOffset + y, size, size);
}
}
g2.setColor(Color.BLACK);
g2.drawRect(xOffset, yOffset, size * 10, size * 10);
}
}
}
Sorry, I optimised your drawing code, now it can resize based on the available space.
Also, you should NEVER update the state of the UI from within any paint method (like calling setBackground), this is a very bad idea which could lead into an infinite paint loop which would consume your CPU cycles and render your system unusable (yes, I've done this)
As a general rule of thumb, you should prefer paintComponent over paint. See Painting in AWT and Swing and Performing Custom Painting for more details
I've managed to finish this task on my own. Here's the code in case someone will have similar problem.
public void paint(Graphics g) {
super.paint(g);
rysujWarcaby((Graphics) g, 50, 50);
rysujWarcaby((Graphics) g, 50, 500);
rysujWarcaby((Graphics) g, 500, 50);
rysujWarcaby((Graphics) g, 500, 500);
}
public void rysujWarcaby(Graphics g, int x, int y) {
int xx = 1;
int nr = 9;
setBackground(Color.YELLOW);
Graphics2D g2 = (Graphics2D) g;
Stroke lineStroke = new BasicStroke(3.0f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER);
g2.setStroke(lineStroke);
g2.setColor(Color.BLACK);
for (int i = 0; i < nr; i++) {
xx = i * 50;
g2.draw(new Line2D.Double(x + xx, y, xx + x, y + 50 * 8));
g2.draw(new Line2D.Double(x, y + xx, x + 50 * 8, y + xx));
}
}
I have a program that I am writing and I need it to both draw a tree and plot its points.
The issue:
My paint seems to go under my graph/plot even though they are in two panels. What can I do so that they do not overlap. Maybe even a scroll bar?
Here is an example Left is with the graph overlapping, right is showing what is underneath.
Bonus:
What is a better way to draw the tree, some of the nodes overlap.
Code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import org.jfree.chart.*;
import org.jfree.chart.axis.Axis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
public class ui extends JFrame {
JPanel tp,chartPanel;
Tree t;
Node root;
Parser p;
double x = 0, y = 0;
int generation = 0;
int timeSeconds = 0;
double fitness = Double.MIN_VALUE;
int sizeX = 1000;
int sizeY = 1000;
int depth = 10;
public ui() {
super("Simple Tree");
setSize(sizeX, sizeY);
setDefaultCloseOperation(EXIT_ON_CLOSE);
tp = new TPanel();
tp.setLayout(new BorderLayout());
chartPanel = new TPanel();
chartPanel.setLayout(new BorderLayout());
//JButton genButton = new JButton("Generate Tree");
//tp.add(genButton);
add(tp);
add(chartPanel);
}
public ChartPanel GraphTree(Node n){
XYSeriesCollection dataSet = new XYSeriesCollection();
XYSeries series = new XYSeries("Data");
XYSeries actual = new XYSeries("Actual");
Parser p = new Parser();
for(double index = -10; index < 10; index+=0.1){
series.add(index, p.TreeOutputAtPoint(n,index));
}
dataSet.addSeries(series);
JFreeChart jc = ChartFactory.createXYLineChart("Tree Graph", "Input", "Output",dataSet,
PlotOrientation.VERTICAL, true, true, false);
ChartPanel cp = new ChartPanel(jc);
cp.setPreferredSize(new java.awt.Dimension(200, 500));
cp.setVisible(true);
chartPanel.add(cp, BorderLayout.SOUTH);
chartPanel.validate();
chartPanel.removeAll();
chartPanel.revalidate();
//tp.repaint();
return cp;
}
public void drawTree(Node r, int gen, double fit, int timeSec){
root = r;
p = new Parser();
generation = gen;
timeSeconds = timeSec;
fitness = fit;
}
class TPanel extends JPanel {
public TPanel() {
setPreferredSize(new Dimension(sizeX, sizeY));// fill whole frame
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(root != null){
Eval(root, g, sizeX/2, 100);
g.drawString("Generation: " + generation, 15, 100);
g.drawString("Time it took: " + timeSeconds + " seconds", 15, 120);
g.drawString("Fitness: " + fitness, 15, 140);
}
}
}
public static void Eval(Node input, Graphics g, int x, int y) {
g.drawString(input.data, x, y);
if (!input.leaf) {
g.drawLine(x, y + 5, x - 20, y + 20);
Eval(input.left, g, x - 30, y + 30);
if (!Utility.isUnary(input.data)) {
g.drawLine(x, y + 5, x + 20, y + 20);
Eval(input.right, g, x + 30, y + 30);
}
}
}
}
https://github.com/kevkid/GeneticAlgorithmTest/blob/master/GeneticAlgorithmTest/src/ui.java
Any help would be appreciated.
I am an enthusiast rather than a programmer. I have thousands of pdf files to go through and extract some data. The data is in X inside boxes (I suspect a graphic within the pdf) there is no evidence of this data if I convert the PDF to text so...
I am converting the PDF to image then looking at the image in certain areas where I expect the X to be and counting black pixels, so far so good.
The PDF does not fit in the window height-wise so I need to add a scrollbar.
I don't understand how I can add a scrollbar to the main window.
Can someone just steer me in the right direction
Thank you
The code is incomplete but working:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
public class ImageViewer {
public static void main(String[] args){
EventQueue.invokeLater(new Runnable()
{
public void run(){
ImageFrame frame = new ImageFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
);
}
}
class ImageFrame extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
public ImageFrame(){
setTitle("Image Viewer");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
ImageComponent component = new ImageComponent();
add(component);
}
public static final int DEFAULT_WIDTH = 860;
public static final int DEFAULT_HEIGHT = 1000;
}
class ImageComponent extends JComponent{
/**
*
*/
private static final long serialVersionUID = 1L;
private Image image;
public ImageComponent(){
try{
File image2 = new File("Files/4.jpg");
image = ImageIO.read(image2);
}
catch (IOException e){
e.printStackTrace();
}
}
public void paintComponent (Graphics g){
if(image == null) return;
int imageWidth = image.getWidth(this);
int imageHeight = image.getHeight(this);
g.drawImage(image, 0, 0, this);
// Draw on the BufferedImage via the graphics context.
g.setColor(Color.RED);
g.drawRect(445, 153, 20, 20);
g.drawRect(552, 153, 20, 20);
g.drawRect(661, 153, 20, 20);
g.drawRect(445, 182, 20, 20);
g.drawRect(552, 182, 20, 20);
g.drawRect(661, 182, 20, 20);
g.drawRect(445, 226, 20, 20);
g.drawRect(552, 226, 20, 20);
g.drawRect(661, 226, 20, 20);
g.drawRect(445, 271, 20, 20);
g.drawRect(552, 271, 20, 20);
g.drawRect(661, 271, 20, 20);
for (int i = 0; i*imageWidth <= getWidth(); i++)
for(int j = 0; j*imageHeight <= getHeight();j++)
if(i+j>0) g.copyArea(0, 0, imageWidth, imageHeight, i*imageWidth, j*imageHeight);
//Count black pixels to see if the box contains an X
int A1 = 0;
for (int y = 153; y < 173; y++)
{
for (int x = 445; x < 465; x++)
{
int c = ((BufferedImage) image).getRGB(x,y);
Color color = new Color(c);
if (c != -1)
{
A1++;
}
}
}
System.out.println("First box pixel count = " + A1);
//Count black pixels to see if the box contains an X
int A2 = 0;
for (int y = 153; y < 173; y++)
{
for (int x = 552; x < 572; x++)
{
int c = ((BufferedImage) image).getRGB(x,y);
if (c != -1)
{
A2++;
}
}
}
System.out.println("Second box pixel count = " + A2);
//Count black pixels to see if the box contains an X
int A3 = 0;
for (int y = 153; y < 173; y++)
{
for (int x = 661; x < 681; x++)
{
int c = ((BufferedImage) image).getRGB(x,y);
if (c != -1)
{
A3++;
}
}
}
System.out.println("Third box pixel count = " + A3);
}
}
Look for something like JScrollPane myPane = new JScrollPane();
Here is the code for a dice game that I am working on that outputs the results to a window. The paint method repeats twice, which is not good for me because I want the dice to roll once and then move on to the next frame. Please someone help me with this problem. Thank you in advance.
import java.awt.*;
import java.util.Random;
import javax.swing.*;
public class Dice extends JApplet {
public static int pause(int n)
{
try {
Thread.sleep(n);
} catch(InterruptedException e) {
}
return n;
}
public void Dice() {
JApplet app = new Dice();
JFrame frame = new JFrame("Dice Game");
frame.setBounds(30, 50, 1300, 650);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(app);
}
public void paint(Graphics g) {
int width = getWidth();
int height = getHeight();
int num = 0;
for (int i = 0; i < 7; i++) {
Random generator= new Random();
int number = generator.nextInt(6)+1;
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
g.setColor(Color.BLACK);
g.drawRoundRect(550, 150, 200, 200, 50, 50);
System.out.println("Test");
if (number == 1) { //Roll one
num = 1;
g.setColor(new Color (0, 0, 0));
g.fillOval(640, 240, 20, 20);
pause(100);
} if (number == 2) { //Roll two
num = 2;
g.setColor(new Color (0, 0, 0));
g.fillOval(590, 290, 20, 20);
g.fillOval(690, 190, 20, 20);
pause(100);
} if (number == 3) { //Roll three
num = 3;
g.setColor(new Color (0, 0, 0));
g.fillOval(590, 290, 20, 20);
g.fillOval(640, 240, 20, 20);
g.fillOval(690, 190, 20, 20);
pause(100);
} if (number == 4) { //Roll four
num = 4;
g.setColor(new Color (0, 0, 0));
g.fillOval(590, 290, 20, 20);
g.fillOval(590, 190, 20, 20);
g.fillOval(690, 290, 20, 20);
g.fillOval(690, 190, 20, 20);
pause(100);
} if (number == 5) { //Roll five
num = 5;
g.setColor(new Color (0, 0, 0));
g.fillOval(590, 290, 20, 20);
g.fillOval(590, 190, 20, 20);
g.fillOval(640, 240, 20, 20);
g.fillOval(690, 290, 20, 20);
g.fillOval(690, 190, 20, 20);
pause(100);
} if (number == 6) { //Roll six
num = 6;
g.setColor(new Color (0, 0, 0));
g.fillOval(590, 190, 20, 20);
g.fillOval(590, 240, 20, 20);
g.fillOval(590, 290, 20, 20);
g.fillOval(690, 190, 20, 20);
g.fillOval(690, 240, 20, 20);
g.fillOval(690, 290, 20, 20);
pause(100);
}
}
g.setFont(new Font("TimesRoman", Font.PLAIN, 20));
g.drawString("You rolled a " + num, 590, 100);
pause(1000);
}
}
The short answer is - you can't. You don't control when painting occurs that is the domain of the RepaintManager.
You should also NEVER call Thread.sleep within the context of the Event Dispatching Thread and especially not within any paint method
You should avoid overriding paint and instead use paintComponent
You should avoid extending from JFrame and instead use something like JPanel, which actually has a paintComponent method.
Animation of this nature is best achieved by using a Swing Timer, which will allow to employee a pause which is maintained outside of the EDT, but is triggered again within in the EDT making it safer to perform painting and updates
Take a look at
Concurrency in Swing
How to Use Swing Timers
Performing Custom Painting
Painting in AWT and Swing
For more details about how painting works in Swing and how to achieve what you are trying to do
Updated with working example
Cause I'm lazy, I've utilised the Graphics 2D API to draw the dots. I did this because many of the dots appear in the same locations for many of the numbers...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DiceRoller {
public static void main(String[] args) {
new DiceRoller();
}
public DiceRoller() {
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.add(new Die());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class Die extends JPanel {
private int number = 1;
public Die() {
Timer timer = new Timer(500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
number = (int) (Math.round((Math.random() * 5) + 1));
repaint();
}
});
timer.setRepeats(true);
timer.setInitialDelay(0);
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(220, 220);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth();
int height = getHeight();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
g2d.setColor(Color.BLACK);
g2d.drawRoundRect(10, 10, width - 20, height - 20, 50, 50);
List<Shape> dots = new ArrayList<>(6);
if (number == 1 || number == 3 || number == 5) {
int x = (width - 20) / 2;
int y = (height - 20) / 2;
dots.add(new Ellipse2D.Float(x, y, 20, 20));
}
if (number == 2 || number == 3 || number == 4 || number == 5 || number == 6) {
int x = ((width / 2) - 20) / 2;
int y = ((height / 2) - 20) / 2;
dots.add(new Ellipse2D.Float(x, y, 20, 20));
dots.add(new Ellipse2D.Float(x + (width / 2), y + (height / 2), 20, 20));
}
if (number == 4 || number == 5 || number == 6) {
int x = (width / 2) + (((width / 2) - 20) / 2);
int y = ((height / 2) - 20) / 2;
dots.add(new Ellipse2D.Float(x, y, 20, 20));
dots.add(new Ellipse2D.Float(x - (width / 2), y + (height / 2), 20, 20));
}
if (number == 6) {
int x = (((width / 2) - 20) / 2);
int y = (height - 20) / 2;
dots.add(new Ellipse2D.Float(x, y, 20, 20));
dots.add(new Ellipse2D.Float(x + (width / 2), y, 20, 20));
}
for (Shape dot : dots) {
g2d.fill(dot);
}
g2d.dispose();
}
}
}
I am trying to find a way to determine a winner and I am not having much luck. The program is suppose to run three laps and which ever car finish all the laps first is the winner. I can get 3 "laps" in but it is not a very good way of doing it. I am hoping someone can show me a better way and also how I can can "count" those laps for the specific winning car. The number of cars is random from 2 - 4 and the "speed" is also random. Can someone help me please. Some code would be nice.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
public class RacingCar extends JFrame {
public RacingCar() {
int x = (int)(Math.random() * 3) + 2;
setLayout(new GridLayout(x, 1, 5,5));
for (int i = 0; i < x; i++){
add(new CarImage());
}
}
public static void main(String[] args) {
JFrame frame = new RacingCar();
frame.setTitle("Racing Car");
frame.setSize(1200, 350);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
class CarImage extends JPanel {
protected int x = 0;
protected int y = 350;
protected int z = 1200;
protected int c = 0;
public CarImage() {
int j = (int)(Math.random() * 500) + 2;
Timer timer1 = new Timer(j, new ActionListener(){
public void actionPerformed(ActionEvent e) {
x += 10;
c ++;
repaint();
}
});
timer1.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
//x = 0;
y = getHeight();
z = getWidth();
g.setColor(Color.WHITE);
g.fillRect(0, 0, z, y);
Polygon polygon = new Polygon();
polygon.addPoint(x + 10, y - 21);
polygon.addPoint(x + 20, y - 31);
polygon.addPoint(x + 30, y - 31);
polygon.addPoint(x + 40, y - 21);
if (x < z - 50) {
g.setColor(Color.BLACK);
g.fillOval(x + 10, y - 11, 10, 10);
g.fillOval(x + 30, y - 11, 10, 10);
g.setColor(Color.BLUE);
g.fillRect(x, y - 21, 50, 10);
g.setColor(Color.GRAY);
g.fillPolygon(polygon);
g.setColor(Color.RED);
}
else {
x = 0;
/*if (c < z - 86) {
g.drawString("Clint's Car", c, y - 51);
}
else {
c = 0;
}*/
}
}
}
}
What I did for the laps loop is this:
if (k < 341){
repaint();
k++;
{
this loop was inserted at the end of:
public void paintComponent(Graphics g) {
I really am stuck here. Thanks for all the help.
Give this code a try
New RacingCar.java
By the way I made your timer be faster in order to not wait 3 laps on really slow races! :P