Related
I want to make a simple addition program. In it I want to pass variables from Main_Window to Second_Window for addition and I want to get result on Second_Window multiple times. Means If I pass variables multiple times from Main_Window for addition then result should be on Second_Window not third and fourth Window.
Here I want All changes should be show on Second_Window not another on open.
These lines are written for passing variables from Main_Window.
Second_Window s = new Second_Window(a,b);
s.setVisible(true);
I'm going to take my code from my previous answer to one of your questions as my base code and add some functionality to it:
First of all, you need to create one and only one instance of your second window and have a method that can update the angles sent to it.
How do you do that you might be asking yourself, well it's easy, in your action listener you create the instance if the second frame was not created yet and updated it otherwise.
private ActionListener listener = e -> {
if (e.getSource().equals(submitButton)) {
if (!frame.isVisible()) {
circle = new MyCircle((Integer) box1.getSelectedItem(), (Integer) box2.getSelectedItem());
frame.add(circle);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
} else {
circle.updateAngles((Integer) box1.getSelectedItem(), (Integer) box2.getSelectedItem());
}
}
};
Note:
If you close the second window all previous data will be lost, if you want to save that state, then play with the frame visibility and initialize the MyCircle instance in the createAndShowGui() method in the code below.
Next thing is you need to keep track of all the angles you've added, for that you might need a List and iterate over it, or paint that to a BufferedImage and then paint that image on the JPanel. For this example we'll be using the List option.
However, for this example, if the data is too much, it might not display, to correct that, use a JScrollPane as well, however I'm leaving that up to you.
This example as well, makes the whole program to terminate only when you close the main window, but not if you close the second window.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class RadiusDrawer {
private JFrame frame;
private JFrame mainFrame;
private int centerX = 50;
private int centerY = 50;
private int x1 = 0;
private int y1 = 0;
private int x2 = 0;
private int y2 = 0;
private int r = 100;
private JComboBox<Integer> box1;
private JComboBox<Integer> box2;
private JLabel label1;
private JLabel label2;
private JButton submitButton;
MyCircle circle;
private static final Integer[] ANGLES = new Integer[]{15, 30, 45, 60, 75, 90};
public static void main(String[] args) {
SwingUtilities.invokeLater(new RadiusDrawer()::createAndShowGui);
}
private void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
mainFrame = new JFrame("Main Frame");
mainFrame.add(createMainWindow());
mainFrame.pack();
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private ActionListener listener = e -> {
if (e.getSource().equals(submitButton)) {
if (!frame.isVisible()) {
circle = new MyCircle((Integer) box1.getSelectedItem(), (Integer) box2.getSelectedItem());
frame.add(circle);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
} else {
circle.updateAngles((Integer) box1.getSelectedItem(), (Integer) box2.getSelectedItem());
}
}
};
private JPanel createMainWindow() {
JPanel pane = new JPanel();
box1 = new JComboBox<>(ANGLES);
box2 = new JComboBox<>(ANGLES);
label1 = new JLabel("Angle 1");
label2 = new JLabel("Angle 2");
submitButton = new JButton("Submit");
submitButton.addActionListener(listener);
pane.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(20, 30, 20, 30);
pane.add(box1, gbc);
gbc.gridx = 1;
pane.add(box2, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
pane.add(label1, gbc);
gbc.gridx = 1;
pane.add(label2, gbc);
gbc.gridy = 2;
pane.add(submitButton, gbc);
return pane;
}
#SuppressWarnings("serial")
class MyCircle extends JPanel {
int cx = 0;
int cy = 0;
double lineX = 0;
double lineY = 0;
double roundedX = 0;
double roundedY = 0;
int angle1 = 0;
int angle2 = 0;
int angle1HistoryX = 15;
int angle2HistoryX = 150;
int angleHistoryY = 300;
int angleHistoryYGap = 20;
Color angle1Color = Color.BLUE;
Color angle2Color = Color.RED;
List <Integer> angle1History;
List <Integer> angle2History;
public MyCircle(int angle1, int angle2) {
this.angle1 = angle1;
this.angle2 = angle2;
angle1History = new ArrayList<>();
angle2History = new ArrayList<>();
angle1History.add(angle1);
angle2History.add(angle2);
calculateCoords();
calculateCenter();
}
private void updateAngles(int angle1, int angle2) {
this.angle1 = angle1;
this.angle2 = angle2;
angle1History.add(angle1);
angle2History.add(angle2);
calculateCoords();
this.revalidate();
this.repaint();
}
private void calculateCoords() {
x1 = (int) (r * Math.cos(Math.toRadians(angle1)));
y1 = (int) (r * Math.sin(Math.toRadians(angle1))) * -1;
x2 = (int) (r * Math.cos(Math.toRadians(angle2)));
y2 = (int) (r * Math.sin(Math.toRadians(angle2))) * -1;
}
private void calculateCenter() {
cx = centerX + r;
cy = centerY + r;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
drawCircle(g2d, centerX, centerY, r);
drawRadius(g2d);
drawHistory(g2d);
}
private void drawCircle(Graphics2D g2d, int x, int y, int r) {
g2d.setColor(Color.BLACK);
g2d.draw(new Ellipse2D.Double(x, y, r * 2, r * 2));
}
private void drawRadius(Graphics2D g2d) {
g2d.setColor(angle1Color);
g2d.draw(new Line2D.Double(cx, cy, cx + x1, cy + y1));
g2d.setColor(angle2Color);
g2d.draw(new Line2D.Double(cx, cy, cx + x2, cy + y2));
}
private void drawHistory(Graphics2D g2d) {
g2d.setColor(angle1Color);
g2d.drawString("Angle1", angle1HistoryX, angleHistoryY);
for (int i = 0; i < angle1History.size(); i++) {
g2d.drawString(angle1History.get(i).toString(), angle1HistoryX, angleHistoryY + (angleHistoryYGap * (i + 1)));
}
g2d.setColor(angle2Color);
g2d.drawString("Angle2", angle2HistoryX, angleHistoryY);
for (int i = 0; i < angle2History.size(); i++) {
g2d.drawString(angle2History.get(i).toString(), angle2HistoryX, angleHistoryY + (angleHistoryYGap * (i + 1)));
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 600);
}
}
}
That's it!
So basically you want to keep the second window to maximum one instance (or zero if the button in main window is never clicked), to do this you need to keep a static reference to the second window, if this reference already exists, you don't create a new one, but ask the existing one to display the calculation result.
A possible approach:
For the submit button in main window, you gather the values of the required parameters, and call the static method of the second window class. A static method is a method that belongs to a class, not an object.
btnSubmit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent aE) {
int azimuth = ...;
int elevation = ...;
SecondWindow.showResult(azimuth, elevation);
}
});
In the second window class, it keeps a static instance of this class, it is null initially. When showResult() is called, it checks if the instance isn't yet exists, then create a new second window and assign to the static reference. And it asks the instance to calculate and display the result in UI.
public class SecondWindow extends JFrame {
private static SecondWindow instance = null;
public static void showResult(int azimuth, int elevation) {
if (instance == null) {
instance = new SecondWindow();
}
instance.performShowResult(azimuth, elevation);
}
private void performShowResult(int azimuth, int elevation) {
// Display the result in UI.
}
}
The last thing to consider is whether you want to set the instance to null when it has been closed? If yes, add this code to the second window constructor:
public SecondWindow() {
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent aE) {
instance = null;
}
});
}
So when showResult() is called again, a new second window will be created.
If you think the creation of second window is somewhat "heavy", then you can just keep the second window closed (thus not set the instance to null), but ensure it is shown when showResult() is called. Like this:
public static void showResult(int azimuth, int elevation) {
if (instance == null) {
instance = new SecondWindow();
} else if (instance.isShowing() == false) {
instance.setVisible(true);
}
instance.performShowResult(azimuth, elevation);
}
I am very new to this community. I have tried to get up to speed on all rules before posting this question (as well as researching solutions). I apologize if I offended or broke any rules through ignorance. Please also excuse my awful code, I am still learning. Thank you for understanding!
EDIT: I have added additional information and tried different approaches to this issue I'm having. I have reworked part of the code below.
I am building a simple football game with a game field panel and control panel. The game field displays all of the player and tackles on the GUI. The control panel sets the difficulty of the game, starts the timer, and the type of quarterback. I ran into a road block where I have all of my code to compile correctly, but when calling set methods on the GameField class to update the score, it updates the variable but not the actual score through my JTextArea Score keeper.
I have instantiated the ControlPanel within the GameField class. I've also tested with a System.out.println() and it shows that it is indeed updating the variable. Is updating JTextArea allowed between classes?
GameField.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class GameField extends JPanel implements KeyListener {
ControlPanel cp = new ControlPanel();
// Game pieces
private JButton playerIcon = new JButton("RB");
private JButton tackleIcon1 = new JButton("LB");
private JButton tackleIcon2 = new JButton("LB");
private JButton fieldGoal = new JButton("FG");
// Player and Tackle locations
private int playerPositionX = 100;
private int playerPositionY = 500;
private int tackle1PositionX = 1200;
private int tackle1PositionY = 400;
private int tackle2PositionX = 1200;
private int tackle2PositionY = 600;
// Player variable speeds
private int playerSpeed = 20;
public GameField() {
setLayout(null);
setBackground(Color.green);
add(playerIcon);
playerIcon.setBounds(new Rectangle(getPlayerPositionX(), getPlayerPositionY(), 80, 30));
add(tackleIcon1);
tackleIcon1.setBounds(new Rectangle(getTackle1PositionX(), getTackle1PositionY(), 100, 50));
add(tackleIcon2);
tackleIcon2.setBounds(new Rectangle(getTackle2PositionX(), getTackle2PositionY(), 100, 50));
add(fieldGoal);
fieldGoal.setBounds(new Rectangle(1600, 100, 100, 800));
playerIsTackled();
setFocusable(true);
addKeyListener(this);
}
public void playerIsTackled() {
Rectangle playerRect = playerIcon.getBounds();
Rectangle tackle1Rect = tackleIcon1.getBounds();
Rectangle tackle2Rect = tackleIcon2.getBounds();
if (playerRect.intersects(tackle1Rect) || playerRect.intersects(tackle2Rect)) {
setPlayerPositionX(100);
setPlayerPositionY(500);
setTackle1PositionX(1200);
setTackle1PositionY(400);
setTackle2PositionX(1200);
setTackle2PositionY(600);
playerIcon.setBounds(getPlayerPositionX(), getPlayerPositionY(), 80, 30);
tackleIcon1.setBounds(getTackle1PositionX(), getTackle1PositionY(), 100, 50);
tackleIcon2.setBounds(getTackle2PositionX(), getTackle2PositionY(), 100, 50);
cp.setCurrentTackles(cp.getCurrentTackles() + 1);
System.out.println(cp.getCurrentTackles());
}
}
public void playerScored() {
Rectangle playerRect = playerIcon.getBounds();
Rectangle fieldGoalRect = fieldGoal.getBounds();
if (playerRect.intersects(fieldGoalRect)) {
setPlayerPositionX(100);
setPlayerPositionY(500);
setTackle1PositionX(1200);
setTackle1PositionY(400);
setTackle2PositionX(1200);
setTackle2PositionY(600);
playerIcon.setBounds(getPlayerPositionX(), getPlayerPositionY(), 80, 30);
tackleIcon1.setBounds(getTackle1PositionX(), getTackle1PositionY(), 100, 50);
tackleIcon2.setBounds(getTackle2PositionX(), getTackle2PositionY(), 100, 50);
cp.setCurrentScore(cp.getCurrentScore() + 1);
System.out.println(cp.getCurrentScore());
}
}
public void moveToPlayer() {
if (getTackle1PositionX() > getPlayerPositionX()) {
setTackle1PositionX(getTackle1PositionX() - 1);
} else {
setTackle1PositionX(getTackle1PositionX() + 1);
}
if (getTackle1PositionY() > getPlayerPositionY()) {
setTackle1PositionY(getTackle1PositionY() - 1);
} else {
setTackle1PositionY(getTackle1PositionY() + 1);
}
getTackleIcon1().setBounds(getTackle1PositionX(), getTackle1PositionY(), 100, 50);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
requestFocusInWindow();
playerIsTackled();
playerScored();
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
int k = e.getKeyCode();
if (k == e.VK_LEFT && getPlayerPositionX() > 0) {
setPlayerPositionX(getPlayerPositionX() - getPlayerSpeed());
}
if (k == e.VK_RIGHT && getPlayerPositionX() < 1703) {
setPlayerPositionX(getPlayerPositionX() + getPlayerSpeed());
}
if (k == e.VK_UP && getPlayerPositionY() > 0) {
setPlayerPositionY(getPlayerPositionY() - getPlayerSpeed());
}
if (k == e.VK_DOWN && getPlayerPositionY() < 1089) {
setPlayerPositionY(getPlayerPositionY() + getPlayerSpeed());
}
getPlayerIcon().setBounds(getPlayerPositionX(), getPlayerPositionY(), 80, 30);
}
Below is the ControlPanel.java. In the actionPerformed method, you can see I added a getScore().setText() method for updating the score. It correctly updates the score there if I replace the getCurrentScore() method with any integer.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Hashtable;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class ControlPanel extends JPanel implements ActionListener, ChangeListener {
private JButton start;
private JButton stop;
private JSlider speed;
private JComboBox playerList;
private Timer tim;
private int delay = 1000;
private int i = 0;
private int currentScore = 0;
private int currentTackles = 0;
private JTextArea timer = new JTextArea("Timer: " + 0, 1, 6);
private JTextArea score = new JTextArea("Field Goals: " + currentScore + " Tackles: " + currentTackles, 1, 16);
private String[] playerStyle = {"Slow Runner", "Running Back", "All Star"};
public ControlPanel() {
super();
setBackground(Color.darkGray);
// Game controls
start = new JButton("Start");
stop = new JButton("Stop");
speed = new JSlider(JSlider.HORIZONTAL, 0, 2, 1);
playerList = new JComboBox(getPlayerStyle());
// Slider label
Hashtable labelTable = new Hashtable();
labelTable.put(new Integer(0), new JLabel("Slow"));
labelTable.put(new Integer(1), new JLabel("Normal"));
labelTable.put(new Integer(2), new JLabel("Fast"));
speed.setLabelTable(labelTable);
speed.setPaintLabels(true);
// Combo box dropdown
playerList.setSelectedIndex(1);
// Timer
tim = new Timer(getDelay(), this);
// Add methods
add(start);
add(stop);
add(timer);
add(speed);
add(score);
add(playerList);
// Event listeners
start.addActionListener(this);
stop.addActionListener(this);
speed.addChangeListener(this);
playerList.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox) e.getSource();
String playerChoice = (String) cb.getSelectedItem();
playerList.setSelectedItem(playerChoice);
}
});
// Set focus to false on all game controls
start.setFocusable(false);
stop.setFocusable(false);
speed.setFocusable(false);
playerList.setFocusable(false);
}
#Override
public void actionPerformed(ActionEvent event) {
Object obj = event.getSource();
if (obj == getTim()) {
setI(getI() + 1);
getTimer().setText("Timer: " + getI());
getScore().setText("Field Goals: " + getCurrentScore() + " Tackles: " + getCurrentTackles());
}
if (obj == getStop()) {
getTim().stop();
}
if (obj == getStart()) {
getTim().start();
}
}
#Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
int currentSpeed = (int) source.getValue();
if (currentSpeed == 0) {
int delaySpeed = getTim().getDelay();
delaySpeed = (int) 2000;
getTim().setDelay(delaySpeed);
}
if (currentSpeed == 1) {
int delaySpeed = getTim().getDelay();
delaySpeed = (int) 1000;
getTim().setDelay(delaySpeed);
}
if (currentSpeed == 2) {
int delaySpeed = getTim().getDelay();
delaySpeed = (int) 500;
getTim().setDelay(delaySpeed);
}
}
MyJPanel.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyJPanel extends JPanel {
public MyJPanel() {
super();
setBackground(Color.gray);
setLayout(new BorderLayout());
ControlPanel gm = new ControlPanel();
GameField gf = new GameField();
add(gm, "North");
add(gf, "Center");
}
}
Thanks to #D.B. I have gotten my code to run as intended. Because I only intend to have two JPanels (Control Panel and Game Panel), I added the panels to pass as arguments to each other. After this, the code started working as intended. Thank you for pushing me into the right step! It was such a simple mistake. Special thanks to #DaveyDaveDave for motivating me to push harder!
Changes I made to my main JPanel object:
public class MyJPanel extends JPanel {
ControlPanel gm = new ControlPanel();
GameField gf = new GameField();
public MyJPanel() {
super();
setBackground(Color.gray);
setLayout(new BorderLayout());
add(gm, "North");
add(gf, "Center");
gf.setCp(gm);
gm.setGf(gf);
}
}
Object fileButton = null;
if("Analyze Text File".equals(command)) {
JFileChooser filechooser;
JFileChooser chooser = new JFileChooser();
int returnVal = filechooser.showOpenDialog(getParent());
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = filechooser.getSelectedFile();
String Stext = (String) readFileAsString(file); //String text = textInput.getText();
Map<Integer, Integer> counts = getCounts(text);
int width = counts.size() * BAR_WIDTH;
int max = maxCount(counts);
int height = max * INCREMENT + 100;
int horizon = height - 25;
HistogramPanel panel = new HistogramPanel(width, counts, height, horizon);
//panel.setBorder(new LineBorder(Color.BLACK, 2));
JOptionPane.showMessageDialog(null, panel);
i am creating a java applet where it counts the frequency/occurence of X words, i have worked out how to do the array to work out the frequency depending on what the user inputs, i need to now create a bar chart that adapts to whatever the user inputs, i have wrote up a code for my bar chart but i dont know how to connect it to my array code.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.net.URL;
import java.io.*;
import java.util.HashMap;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Map;
import javax.swing.SwingUtilities;
import javax.swing.JOptionPane;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class assignment_work extends JApplet implements ActionListener {
JTextArea textInput; // User Input.
JLabel wordCountLabel; // To display number of words.
JLabel meanLabel; // To display the mean.
public void init() {
// This code from here is the customisation of the Applet, this includes background colour, text colour, text back ground colour, labels and buttons
setBackground(Color.black);
getContentPane().setBackground(Color.black);
textInput = new JTextArea();
textInput.setWrapStyleWord(true);
JPanel ui = new JPanel();
ui.setLayout(Layout(-1));
/* Creating Analyze and Reset buttons */
JButton chartButton = new JButton("Bar Chart");
chartButton.addActionListener(this);
ui.add(chartButton);
JPanel panel = new JPanel(new BorderLayout())
//panel.add(chartButton, BorderLayout.SOUTH);
/* Labels telling the user what to do or what the program is outputting */
wordCountLabel.setBackground(Color.black);
wordCountLabel.setForeground(Color.red);
wordCountLabel.setOpaque(true);
meanLabel.setBackground(Color.white);
meanLabel.setForeground(Color.black);
meanLabel.setOpaque(true);
watermark.setLayout(new BorderLayout());
watermark.setBackground(Color.darkGray);
/* Border for Applet. */
getContentPane().setLayout( new BorderLayout());
getContentPane().add(ui, BorderLayout.CENTER);
/* Scroll bar for the text area where the user will input the text they wish to analyse. */
JScrollPane scroller = new JScrollPane( textInput );
getContentPane().add(scroller, BorderLayout.CENTER);
getContentPane().add(ui, BorderLayout.NORTH);
}
class CustomCanvas extends Canvas {
public CustomCanvas() {
setBackground(Color.darkGray);
setPreferredSize(new Dimension(100, 100));
}
public void paint(Graphics g) {
int x [] = {20,20,10,10,40,40,30,30};
int y [] = {40,20,20,10,10,20,20,40};
int n = 8;
g.setColor(Color.black);
g.fillPolygon(x,y,n);
int wpoint [] = {45,65,85,75,70,60,55};
int zpoint [] = {40,10,40,40,30,30,40};
int npoint = 7;
g.setColor(Color.black);
g.fillPolygon(wpoint,zpoint,npoint);
int a [] = {60,65,70};
int b [] = {25,20,25};
int npoints = 3;
g.setColor(Color.darkGray);
g.fillPolygon(a,b,npoints);
}
}
private int maxCount(Map<Integer, Integer> counts) {
counts.values()) {
if (num > max) {
max = num;
}
}
return max;
}
public class Panel extends JPanel {
int width;
Map<Integer> count;
public Histogram(int width, Map<Integer, Integer> counts, int horizon) {
this.width = width;
this.dimHeight = dimHeight;
this.horizon = horizon;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = 10;
for (Map.Entry<Int> entry : counts.entrySet()) {
int height = entry.getValue() * INCREMENT;
int y = horizon - height;
g.drawString(entry.getValue() + " Frequency", x, y -2);
x += BAR_WIDTH;
}
}
public Dimension getPreferredSize() {
return new Dimension(width, dimHeight);
}
}
public static Map<Int> getCounts(String Input) {
Map<Integer> map = new HashMap<Int>();
String[] array = Input.split("[\\s.,;:!?()");
for (String array) {
Int size;
if (!map(size)) {
map.put(size, 1);
} else {
map.put(map.get(size) + 1);
}
}
return;
}
// Text analysis end
public void actionPerformed(java.awt.event.ActionEvent e) {
if (command.equals("commands")) {
{
final graph<Int> Lengths = new graph<Int>();
String array = Input.Text().split(");
for (int i = 10; i < array.length; i) {
final int Length = array[0].length();
if( Length.Set().container(Length ) ) {
Integer currentNumberOfOccurences = wordLengths.get(wordLength);
currentNumberOfOccurences;
wordLengths.put(wordLength, currentNumberOfOccurences);
}
wordLengths.put(wordLength, 1);
}
double total =10;
double total = 10;
for (final Int length : Lengths.Set()) {
final Int occurrences = Lengths.get(length);
Length = tLength + (length * occurrencers );
totalOccurrences += occurrences;
}
final mean = aLength / lOccurrences;
aLabel.Text("mean word length is: " + (eLength / wOccurrences) );
// System.out.println("mean word length is: " + (total / length) );
}
String array = textInput.getText().split(" ");
int maxWordLength = 0;
wordLength = array[i].length();
if (wordLength > maxWordLength) {
maxWordLength = wordLength;
}
int[] intArray = new int[maxWordLength + 1];
for (int i = 0; i < array.length; i++) {
intArray[array[i].length()]++;
}
for (int i = 1; i < intArray.length; i++) {
out.printf("%d word(s) of length %d<br>", intArray[i], i)
}
else if (command.equals("Reset")) {
textInput.setText("");
textInput.requestFocus();
}
Object chartButton = null;
if (e.getSource() == chartButton) {
String text = textInput.getText();
HistogramPanel panel = new HistogramPanel(width, counts, height, horizon);
//panel.setBorder(new LineBorder(Color.BLACK, 2));
JOptionPane.showMessageDialog(null, panel);
}
};
}
Update
Using JFileCHooser
private String readFileAsString(String filePath) throws IOException {
StringBuffer fileData = new StringBuffer();
BufferedReader reader = new BufferedReader(
new FileReader(filePath));
char[] buf = new char[1024];
int numRead=0;
while((numRead=reader.read(buf)) != -1){
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
}
reader.close();
return fileData.toString();
}
Here's what you want to do to create the dynamic size from the input.
You need to get the number of entries in the map, then multiply it by whatever you want the width of each bar to be.
You need to get the highest value in the map and multiply that by you increment (to draw) amount and create the height from that.
You create a new JPanel with dimension based on the height and width from the previous two points.
Iterate through the map the draw the bars.
I do the things above in the actionPerformed of a button and I add the JPanel to a JOptionPane. Let me know if you need clarification on anything.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class Histogram {
private static final int BAR_WIDTH = 50;
private static final int INCREMENT = 10;
public Histogram() {
final JTextArea textArea = new JTextArea(5, 40);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
JButton go = new JButton("Histogram-me!");
JPanel panel = new JPanel(new BorderLayout());
panel.add(textArea, BorderLayout.CENTER);
panel.add(go, BorderLayout.SOUTH);
JFrame frame = new JFrame();
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
go.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String text = textArea.getText();
Map<Integer, Integer> counts = getCounts(text);
int width = counts.size() * BAR_WIDTH;
int max = maxCount(counts);
int height = max * INCREMENT + 100;
int horizon = height - 25;
HistogramPanel panel = new HistogramPanel(width, counts, height, horizon);
//panel.setBorder(new LineBorder(Color.BLACK, 2));
JOptionPane.showMessageDialog(null, panel);
}
});
}
private int maxCount(Map<Integer, Integer> counts) {
int max = 0;
for (Integer num : counts.values()) {
if (num > max) {
max = num;
}
}
return max;
}
public class HistogramPanel extends JPanel {
int width;
int dimHeight;
int horizon;
Map<Integer, Integer> counts;
public HistogramPanel(int width, Map<Integer, Integer> counts, int dimHeight, int horizon) {
this.width = width;
this.counts = counts;
this.dimHeight = dimHeight;
this.horizon = horizon;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = 10;
for (Map.Entry<Integer, Integer> entry : counts.entrySet()) {
int height = entry.getValue() * INCREMENT;
int y = horizon - height;
g.fillRect(x, y, BAR_WIDTH - 10, height);
g.drawString(entry.getKey() + " chars", x, horizon + 10);
g.drawString(entry.getValue() + " times", x, y -2);
x += BAR_WIDTH;
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(width, dimHeight);
}
}
public static Map<Integer, Integer> getCounts(String input) {
Map<Integer, Integer> map = new HashMap<>();
String[] array = input.split("[\\s.,;:!?(){}]+");
for (String s : array) {
Integer size = s.length();
if (!map.containsKey(size)) {
map.put(size, 1);
} else {
map.put(size, map.get(size) + 1);
}
}
return map;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Histogram histogram = new Histogram();
}
});
}
}
how can I keep the previous changes using repaint() and run() or is there another solution for this.
I have this code running well. This code paints 3 ovals. When I put an input for the x-coordinate at the text box, it paints/draws the new oval. However, everytime I input and change the x-coordinate at the text box, the oval just relocates. What I want to do is to retain the previous changes that I have made. For example, I get 3 ovals at start when you hit the see coordinates button then you get 4 and so on after you input and click the add coordinate button.
Here's my code:
/deleted/
Any help would be much appreciated.
[EDIT]
I'm implementing K-nearest neighbors. So far what I have made are:
1.created a gray panel of size 500x500 from (0,0)
2.gets file using browse button.
3.gets string and tokenize
4.token[0]= k-nearest, token[1]= total neighbors
5.token[2]= x-coordinate, token[3]= y-coordinate, token[4]= type of cluster and so on.
6.input x-coord and y-coord
7.compute distance between coordinates from txt file and input
8.draw shape according to minimum distance
Here's my code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.*;
import java.lang.Math;
public class Knn extends JFrame implements ActionListener{
JPanel grid,panel;
JLabel xlab,ylab;
JTextArea xtex,ytex,temp;
JButton cbut,fbut;
String text;
int k, ktotal, x, y,xcori,ycori;
String[] token;
int[] itoken;
boolean paint=false, paintclass=false;
double ans,xcord,ycord;
double[] dtoken,ansarray,xarray,yarray;
Map<Double, Double> anshash;
public Knn(){
super("K-Nearest Neighbor");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600,500);
//this.pack();
this.setVisible(true);
this.setResizable(true);
this.setLayout(null);
grid= new JPanel();
grid.setBackground(Color.GRAY);
grid.setBounds(0,0,500,500);
panel= new JPanel();
//panel.setLayout(null);
panel.setBounds(500,0,100,100);
temp= new JTextArea();
xlab= new JLabel("X");
xtex= new JTextArea("",1,7);
ylab= new JLabel("Y");
ytex= new JTextArea("",1,7);
cbut= new JButton("classify");
fbut= new JButton("Browse");
panel.add(xlab);
panel.add(xtex);
panel.add(ylab);
panel.add(ytex);
panel.add(cbut);
panel.add(fbut);
this.add(grid);
this.add(panel);
fbut.addActionListener(this);
cbut.addActionListener(this);
}
public double formula(double x1, double y1, double x2, double y2){
double tmpans= Math.pow((x2-x1),2.0) + Math.pow((y2-y1),2.0);
ans= Math.sqrt(tmpans);
return ans;
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==fbut){ //choose file input coordinates
JFileChooser fileChooser= new JFileChooser();
int returnVal = fileChooser.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION){
File file = fileChooser.getSelectedFile();
try {
//output file content to text box, copy to a string
temp.read( new FileReader(file.getAbsolutePath()),null);
text= temp.getText();
}catch(IOException ex){
ex.printStackTrace();
}
}
token = text.split("\\W+");
itoken=new int[token.length];
int i=0;
for (String str : token){
itoken[i++] = Integer.parseInt(str); //convert from string to integer
}
for (i = 4; i < itoken.length; i += 3) { //x50
itoken[i-2]= itoken[i-2] * 50;
itoken[i-1]= itoken[i-1] * 50;
}
paint=true;
repaint();
}
if(e.getSource()==cbut){
solveClass();
}
}
public void paint(Graphics g){
super.paint(g);
if (paint) {
for (int i = 4; i < itoken.length; i += 3) {
x = itoken[i-2];
y = itoken[i-1];
if(itoken[i]==1)
g.fillRect(x - 5, y - 5, 10, 10);
if(itoken[i]==2)
g.fillOval(x - 5, y - 5, 10, 10);
if(itoken[i]==3)
g.drawOval(x - 5, y - 5, 10, 10);
}
}
if(paintclass){
if(anshash.get(ansarray[0])==1)
g.fillRect(xcori - 5, ycori - 5, 10, 10);
if(anshash.get(ansarray[0])==2)
g.fillOval(xcori - 5, ycori - 5, 10, 10);
if(anshash.get(ansarray[0])==3)
g.drawOval(xcori - 5, ycori - 5, 10, 10);
}
}
public void solveClass(){
String xcors= xtex.getText();
String ycors= ytex.getText();
dtoken=new double[itoken.length];
xarray=new double[itoken[1]];
yarray=new double[itoken[1]];
ansarray=new double[itoken[1]];
int j=0;
for (String str : token)
dtoken[j++] = Double.parseDouble(str); //convert from string to double
//convert to int
xcori= Integer.parseInt(xcors);
ycori= Integer.parseInt(ycors);
//convert to double
xcord= Double.parseDouble(xcors);
ycord= Double.parseDouble(ycors);
int q=0;
for (int i = 3; i < itoken.length; i += 3) {
xarray[q]= dtoken[i-1];
yarray[q]= dtoken[i];
q++;
}
for (int i = 0; i < xarray.length; i ++)
ansarray[i]= formula(xcord,ycord,xarray[i]*50,yarray[i]*50); //x50
anshash= new HashMap<Double,Double>();
int r=0;
for(int i = 4; i < itoken.length; i += 3){
anshash.put(ansarray[r], dtoken[i]);
r++;
}
Arrays.sort(ansarray); //sort
paintclass=true;
repaint();
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Knn knn= new Knn();
}
});
}
}
Here's the text file:
3 5
1 2 1
4 3 2
7 5 2
6 9 3
5 5 1
"However, everytime I input and change the x-coordinate at the text box, the oval just relocates. What I want to do is to retain the previous changes that I have made"
Use a List of ball objects. Here is the Ball class
public class Ball {
int x;
int y;
public Ball(int x, int y) {
this.x = x;
this.y = y;
}
public void drawball(Graphics g) {
g.fillOval(x, y, 20, 20);
}
}
Here is the JPanel class
public class BallPanel extends JPanel {
private List<Ball> balls;
#Override
protected void paintComponent(Graphics g) {
super.paintCompoent(g);
for (Ball ball: balls) {
ball.drawBall(g);
}
}
}
The basic point is to keep a data structure of the ball locations. You may also want to have getters and setters for the x and y so you can manipulate their locations.
To add more balls, all you need to do is add to the List a new Ball(...) and call repaint();
Here's a running example. Just type in an x and a y less than 500 and click the button. You will see more balls being added. You can see in the actionPerformed where I add a new Ball and the in the paintCompoent where I loop though the ball List
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class TestBall extends Frame implements ActionListener {
private JTextField enterX;
private JTextField enterY;
private JLabel labelX;
private JLabel labelY;
private JButton addBall;
private List<Ball> balls;
private BallPanel ballPanel;
public TestBall() {
balls = new ArrayList<>();
ballPanel = new BallPanel();
JPanel p1 = new JPanel();
labelX = new JLabel("Enter X");
enterX = new JTextField(6);
labelY = new JLabel("Enter Y");
enterY = new JTextField(6);
addBall = new JButton("Add Ball");
addBall.addActionListener(TestBall.this);
p1.add(labelX);
p1.add(enterX);
p1.add(labelY);
p1.add(enterY);
p1.add(addBall);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(ballPanel, BorderLayout.CENTER);
frame.add(p1, BorderLayout.PAGE_START);
frame.pack();
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
int x = Integer.parseInt(enterX.getText());
int y = Integer.parseInt(enterY.getText());
balls.add(new Ball(x, y));
ballPanel.repaint();
}
public class BallPanel extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Ball ball : balls) {
ball.drawBall(g);
}
}
}
public class Ball {
int x;
int y;
public Ball(int x, int y) {
this.x = x;
this.y = y;
}
public void drawBall(Graphics g) {
g.fillOval(x, y, 20, 20);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TestBall();
}
});
}
}
So I have the following code, and whenever I run the program it gives me an error. It all seems correct to me, but it isn't.
It is supposed to take the value of whatever is in the textfields and move the square to that position, and whenever the user enters a new value it is supposed to change the square to whatever the textfield says it should be. Can anybody fix this, or at least tell me whats wrong? Sorry about the code, it got even more screwed up when I started trying to debug it.
The error is
Exception in thread "main" java.lang.NullPointerException
at com.theDevCorner.Game$OptionPanel.<init>(Game.java:228)
at com.theDevCorner.Game$GridPane.<init>(Game.java:81)
at com.theDevCorner.Game.<init>(Game.java:35)
at com.theDevCorner.Game.main(Game.java:52)
Code
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Game extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
private GridPane gridPane;
private DragPanel drag;
public boolean isMouseClicked = false;
public static JMenuBar bar = new JMenuBar();
public int gridY = 1;
public int gridX = 1;
public Game() {
setLayout(new BorderLayout());
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
gridPane = new GridPane();
gridPane.setBorder(BorderFactory.createLineBorder(Color.white));
add(gridPane);
drag = new DragPanel(options);
drag.setBorder(BorderFactory.createLineBorder(Color.white));
drag.setBackground(new Color(100, 100, 125));
add(drag, BorderLayout.WEST);
}
public static void main(String args[]) {
Game game = new Game();
JFrame frame = new JFrame();
frame.setTitle("Game");
frame.setVisible(true);
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(game);
frame.pack();
frame.setLocationRelativeTo(null);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(e);
if (e.getActionCommand().equalsIgnoreCase("grid")) {
gridPane.setGridOn(!gridPane.isGridOn());
}
if (e.getActionCommand().equalsIgnoreCase("square")) {
gridPane.setSqaureOn(!gridPane.isSquareOn());
}
if (e.getActionCommand().equalsIgnoreCase("vgrid")) {
gridPane.setVertOn(!gridPane.isVertOn());
}
}
public class GridPane extends JPanel {
public OptionPanel op = new OptionPanel();
private static final long serialVersionUID = 1L;
private boolean gridOn = false;
private boolean squareOn = false;
private boolean vertOn = false;
public int x = 0,y = 0,w = 0,h = 0;
public GridPane() {
setBackground(Color.BLACK);
}
public boolean isGridOn() {
return gridOn;
}
public boolean isSquareOn() {
return squareOn;
}
public boolean isVertOn() {
return vertOn;
}
public void setGridOn(boolean value) {
if (value != gridOn) {
this.gridOn = value;
repaint();
}
}
public void setVertOn(boolean value) {
if (value != vertOn) {
this.vertOn = value;
repaint();
}
}
public void setSqaureOn(boolean value) {
if (value != squareOn) {
this.squareOn = value;
repaint();
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Toolkit tk = Toolkit.getDefaultToolkit();
if (gridOn) {
System.out.println("Grid works");
g.setColor(Color.white);
for (int i = 0; i < tk.getScreenSize().height; i += 64) {
gridY++;
g.drawLine(0, (64 * gridY), tk.getScreenSize().width, (64 * gridY));
}
}
gridY = -1;
gridX = -1;
if (vertOn) {
System.out.println("vert grid works");
g.setColor(Color.white);
for (int ig = 0; ig < tk.getScreenSize().width; ig += 64) {
gridX++;
g.drawLine((64 * gridX), 0, (64 * gridX), tk.getScreenSize().height);
}
}
if (squareOn) {
System.out.println("Square works");
g.setColor(Color.red);
x = Integer.parseInt(op.squareX.getText());
y = Integer.parseInt(op.squareY.getText());
w = Integer.parseInt(op.squareW.getText());
h = Integer.parseInt(op.squareH.getText());
g.fillRect(x,y,w,h);
}
x = 0;
y = 0;
w = 64;
h = 64;
}
}
public class DragPanel extends JPanel {
OptionPanel op;
public DragPanel(OptionPanel op) {
this.op = op;
this.add(this.op.squareButton);
this.op.squareButton.setActionCommand("square");
}
public void addActionListener(ActionListener listener) {
System.out.println(listener);
this.op.squareButton.addActionListener(listener);
}
}
private static class Square {
}
private class OptionPanel extends JPanel {
public JButton grid;
public JButton vgrid;
public JButton squareButton;
public JTextField squareX;
public JTextField squareY;
public JTextField squareW;
public JTextField squareH;
public int x,y,w,h;
public Square square = new Square();
public OptionPanel() {
//Sets the stuff for the panel
setBackground(new Color(155, 0, 255));
setLayout(new GridBagLayout());
//end
//The Show Grid Button Stuff
grid = new JButton("Show Horizontal Grid");
grid.setActionCommand("grid");
//end
//The vertical grid
vgrid = new JButton("Show Vertical Grid");
vgrid.setActionCommand("vgrid");
//end
//The Square tool button stuff
squareButton = new JButton("Sqaure Tool");
//end
squareX = new JTextField(gridPane.x); //<----- THIS IS WHERE THE PROBLEM IS!!!!!
squareY = new JTextField("1",3);
squareW = new JTextField("1",3);
squareH = new JTextField("1",3);
//The gridbagConstraints things
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTH;
//kind of like padding
gbc.weighty = 1;
//sets the positions
gbc.gridx = 0;
gbc.gridy = 0;
//add it
add(grid, gbc);
//changes position for the second button
gbc.gridx = -1;
gbc.gridy = 0;
// adds it
add(vgrid, gbc);
//end
add(squareX, gbc);
add(squareY, gbc);
add(squareW, gbc);
add(squareH, gbc);
}
public void addActionListener(ActionListener listener) {
//adds action listeners
grid.addActionListener(listener);
vgrid.addActionListener(listener);
squareButton.addActionListener(listener);
squareX.addActionListener(listener);
squareY.addActionListener(listener);
squareW.addActionListener(listener);
squareH.addActionListener(listener);
}
}
Update
I need help with this portion of the code still:
squareX = new JTextField("0" + gridPane.x,3); //<----- THIS IS WHERE THE PROBLEM IS!!!!!
squareY = new JTextField("0" + gridPane.y,3);
squareW = new JTextField("0" + gridPane.w,3);
squareH = new JTextField("0" + gridPane.h,3);
It seems that the main errors are coming from when I try to do something like this...
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
gridPane = new GridPane();
You create the OptionPanel before your create the GridPane, so the gridPane variable is null when your optionPanel tries to access that variable.
Create the gridPane before you create the OptionPanel
Your code should be
gridPane = new GridPane();
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
gridPane.setBorder(BorderFactory.createLineBorder(Color.white));
add(gridPane);
You're first NullPointerException can be fixed by doing something like...
public Game() {
setLayout(new BorderLayout());
gridPane = new GridPane();
gridPane.setBorder(BorderFactory.createLineBorder(Color.white));
OptionPanel options = new OptionPanel();
options.addActionListener(this);
add(options, BorderLayout.NORTH);
add(gridPane);
drag = new DragPanel(options);
drag.setBorder(BorderFactory.createLineBorder(Color.white));
drag.setBackground(new Color(100, 100, 125));
add(drag, BorderLayout.WEST);
}
You're second NullPointerException is more tricky...
You have a cyclic dependency problem...
Class A is trying to create Class B, which is trying to create class C when class C depends on an instance of B...
To clarify...GridPane has an instance of OptionPane, but OptionPane is depended on the state of GridPane, which is null, because GridPane can't initalise until OptionPane has been initialised...confused yet...
You can solve this by using a lazy loading approach. That is, not try to insitate the OptionPane till you need it...
public class GridPane extends JPanel {
public OptionPanel op;
// Other variables...
// Other methods...
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Other paint code...
if (squareOn) {
if (op == null) {
op = new OptionPanel();
}
System.out.println("Square works");
g.setColor(Color.red);
x = Integer.parseInt(op.squareX.getText());
y = Integer.parseInt(op.squareY.getText());
w = Integer.parseInt(op.squareW.getText());
h = Integer.parseInt(op.squareH.getText());
g.fillRect(x, y, w, h);
}
}
}
How ever. I don't think this is going to achieve what you want in the long run, as the state of the OptionPane will be different between the classes...(GridPane and OptionPane won't share the same instance....)
A better solution would be to remove these direct dependencies, so that you can pass some the same reference of some kind of model between GridPane and OptionPane, which would allow it to act as the glue between them...