The goal of the current program is to create a line, of varying thickness, between two points in a window frame. So far, so good.
Next, I would like the program to recognize that the user has made a selection from the JComboBox.
This post, and the code, have been updated. (a) the itemStateChanged method was removed. It was not executed, and so, did not need to be in the program. (b) the actionPerformed method was updated to update whenever any of the objects were modified. (c) the color choice was implemented in perhaps one of the ugliest switch/case statements ever. (there must be a better way). And (d) I implemented the suggestion from Itamar Green, regarding the definition of the JComboBox. Thank you.
What don't I know?
Notes: Java 8.111. O/S: Windows 8.1. IDE: Ecilpse Java EE 4.6.0
All responses towards improving the code or the question are gratefully accepted.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class ThickPen extends JApplet implements ActionListener
{
private static final long serialVersionUID = 1L;
JLabel xStartLabel = new JLabel("X Start");
JLabel yStartLabel = new JLabel("Y Start");
JLabel xStopLabel = new JLabel("X Stop");
JLabel yStopLabel = new JLabel("Y Stop");
JLabel thickLabel = new JLabel("Thickness");
JComboBox<String> myColour;
String theColour = "black";
TextField xStartField = new TextField(4);
int xStart = 0;
TextField yStartField = new TextField(4);
int yStart = 0;
TextField xStopField = new TextField(4);
int xStop = 0;
TextField yStopField = new TextField(4);
int yStop = 0;
TextField thicknessField = new TextField(4);
int thick = 0;
String[] colourString = {"black","blue","cyan","darkgray","gray","green",
"lightGray","magenta","orange","pink","red","white","yellow"};
int theIndex = 0;
public void init()
{
setSize(550,500);
Container content = getContentPane();
setLayout(new FlowLayout());
xStartField.addActionListener(this);
yStartField.addActionListener(this);
xStopField.addActionListener(this);
yStopField.addActionListener(this);
thicknessField.addActionListener(this);
add(xStartLabel);
add(xStartField);
add(yStartLabel);
add(yStartField);
add(xStopLabel);
add(xStopField);
add(yStopLabel);
add(yStopField);
add(thickLabel);
add(thicknessField);
myColour = new JComboBox<String>(colourString);
// JComboBox<String> myColour = new JComboBox<String>(colourString);
myColour.setSelectedIndex(0); // start with black
myColour.addActionListener(this);
add(myColour);
content.setBackground(Color.white);
content.setForeground(Color.black);
}
public void paint(Graphics g)
{
super.paint(g);
Dimension d = getSize();
int fullWidth = d.width;
int fullHeight = d.height;
int deltaX = 0;
int deltaY = 0;
boolean xAxis = false;
System.out.println("So far Start x y: "+xStart+" "+yStart+" color: "+theColour);
if (xStart < 1 || xStart > fullWidth
|| yStart < 1 || yStart > fullHeight
|| xStop < 1 || xStop > fullWidth
|| yStop < 1 || yStop > fullHeight
|| thick < 1 || thick > fullHeight || thick > fullWidth) {
String outStr = "Start and stop numbers must be within this window frame";
String outStr2 = "Current width: "+fullWidth+" height: "+fullHeight;
g.setColor(Color.white);
g.fillRoundRect(d.width/4, d.height/4, 300, 40, 4, 4);
g.setColor(Color.red);
g.drawString(outStr, d.width/4+10, d.height/4+15);
g.drawString(outStr2, d.width/4+10, d.height/4+30);
g.drawString("The index: "+theIndex, d.width/4, 300);
} else {
g.drawString("", d.width/4, 260);
deltaX = Math.abs(xStart - xStop); // determine absolute delta of two Xs
deltaY = Math.abs(yStart - yStop); // determine absolute delta of two Ys
if (deltaX > deltaY) // make line thickness based on x axis if
xAxis = false; // the x axis has the most 'room'.
else // else, use the y axis.
xAxis = true;
pickAColour(g, theColour);
drawMyLine(g, xStart, yStart, xStop, yStop, thick, xAxis);
}
g.drawString("The index: "+theIndex, d.width/4, 300);
g.drawString("The color "+ theColour, d.width/4, 330);
}
public void drawMyLine(Graphics g, int xStart, int yStart,
int xStop, int yStop, int thick, boolean xAxis)
{
int count = 0;
while (count < thick)
{
g.drawLine(xStart, yStart, xStop, yStop);
count++;
if (xAxis) {
xStart++;
xStop++;
} else {
yStart++;
yStop++;
}
}
}
public void pickAColour(Graphics g, String theColour)
{
switch (theColour) {
case "black" :
g.setColor(Color.black);
break;
case "blue" :
g.setColor(Color.blue);
break;
case "cyan" :
g.setColor(Color.cyan);
break;
case "darkgray" :
g.setColor(Color.darkGray);
break;
case "gray" :
g.setColor(Color.gray);
break;
case "green" :
g.setColor(Color.green);
break;
case "lightGray" :
g.setColor(Color.lightGray);
break;
case "magenta" :
g.setColor(Color.magenta);
break;
case "orange" :
g.setColor(Color.orange);
break;
case "pink" :
g.setColor(Color.pink);
break;
case "red" :
g.setColor(Color.red);
break;
case "white" :
g.setColor(Color.white);
break;
case "yellow" :
g.setColor(Color.yellow);
break;
} // end of case statement
} // end of pickAColour
public void actionPerformed (ActionEvent ae)
{
Object source=ae.getSource();
// xStart
// if (source==xStartField)
// {
try {
xStart=Integer.parseInt(
xStartField.getText());
}
catch (NumberFormatException x) {
xStart= -1;
}
// }
// yStart
// else if (source==yStartField)
// {
try {
yStart=Integer.parseInt(
yStartField.getText());
}
catch (NumberFormatException x) {
yStart= -1;
}
// }
// xStop
// else if (source==xStopField)
// {
try {
xStop=Integer.parseInt(
xStopField.getText());
}
catch (NumberFormatException x) {
xStop= -1;
}
// }
// yStop
// else if (source==yStopField)
// {
try {
yStop=Integer.parseInt(
yStopField.getText());
}
catch (NumberFormatException x) {
yStop= -1;
}
// }
// thickness
// else if (source==thicknessField)
// {
try {
thick=Integer.parseInt(
thicknessField.getText());
}
catch (NumberFormatException x) {
thick= -1;
}
// } else {
if (source==myColour) {
JComboBox<String> cb = (JComboBox<String>)ae.getSource();
// String theColour = (String)cb.getSelectedItem(); ///can;
// Integer theIndex = (int)cb.getSelectedIndex();
theColour = (String)cb.getSelectedItem();
theIndex = (int)cb.getSelectedIndex();
}
// }
repaint();
} // end of ActionEvent
} // end of class
Simply put this
myColour = new JComboBox<String>(colourString);
instead of this
JComboBox<String> myColour = new JComboBox<String>(colourString);
in your init method.
The problem is the difference between the myColour defined here (in member section)
JComboBox<String> myColour;
and the one created in the init(). You are initializing the one in the Init but not the one in the member section, so when you are trying to use myColour in actionPreformed, Java is trying to call methods from a reference with no object.
Related
Good afternoon, I am using stm32 Blue Pill on USB raised com - port, development environment "IAR".
The problem is the following, when I connect through the application, the number "3"
does not change to the number "50" after the arrow, but on the contrary is shown next !
See Figure 1.2. I work under the protocol.
How do you achieve this?
I'm using the controlP5 library and cp5.addNumberbox.
Data in "IAR".
int Bullet = 50; // variable for result
sprintf((char *)str, "(,%d,-Ђ",Bullet); // sending a command with data to stm32.
In the code of the Displaydata tab, the line "case 40" is the symbol (
The command can also be sent through the terminal using a virtual com port.
Command: (, 50 ,! Figure 3.
I'll have to lay out the whole little project for you to check it out.
Com_Interface1:
import processing.serial.*;
import controlP5.*;
ControlP5 cp5;
DropdownList serialPortsList;
Serial serialPort;
final int BAUD_RATE = 9600;
char parity = 'N';
int dataBits = 8;
float stopBits = 1.0;
public void setup() {
background(50);
size(700, 420, P3D);
surface.setTitle("TEST");
surface.setResizable(false);
setupUI();
smooth();
frameRate(30);
writeOutgioing[lengthmas-1]=1;
String[] portNames = Serial.list();
//serialPort.clear(); // Why does not it work?
for (int i = 0; i < portNames.length; i++) serialPortsList.addItem(portNames[i], i);
}
public void toplug (int theValue)
{ // Start button on click sends a commad 1.
println("Button click events: "+theValue);
strata =!strata;
if (!strata) {
connection.setLabel("Пуск");
serialPort.dispose();
Vin.setText("Voltage K.V - ");
inputPULI.setLabel("Bullet");
} else {
connection.setLabel("СТОП");
serialports((int)serialPortsList.getValue());
writeOutgioing[0]=1;
writeOut();
}
}
public void serialports(int theValue) {
try {
serialPort = new Serial(this, Serial.list()[theValue], BAUD_RATE, parity, dataBits, stopBits);
serialPort.bufferUntil('\n');
println("COM connected: "+ Serial.list()[theValue] );
/*Send.unlock();
connection.unlock();*/ // locking buttons in applications if not connected via rs-232.
}
catch(Exception e) {
System.err.println("Error opening serial port" + Serial.list()[theValue]);
e.printStackTrace();
}
}
/*void controlEvent(ControlEvent event){
println(event.getController().getName(),"changed value to",event.getValue(),"inputPULI = ",PUL,"inputNapryzenieKV = ",NapryzenieKV,"CheckBoxuvum= ",
UV/UM,"P4 = ",std2,);
}*/
Displaydata:
void Displaydata() {
switch(x)
{
case 20:
// What to write?
// label(testRead[1]+" Мин."); // ImageButton
// min=testRead[1];
break;
case 30:
// What to write?
// P4.setText("std2"+ testRead[1]); // CheckBox
break;
case 40:
inputPULI.setLabel("Bullet: " + testRead[1] );
break;
case 70:
inputNapryzenieKV.setLabel("Voltage: " + testRead[1] );
break;
case 60:
Vin.setText("Voltage K.V: " + testRead[1] + " " + testRead[2]);
break;
case 50:
// What to write?
//CheckBoxuvum.setText("UV/UM - " +testRead[1] ); // RadioButton
break;
default:
println("DisplayData(): no case selected.");
break; // technically not necessary, but I like my switches tidy
}
}
GUI:
int PUL;
float NapryzenieKV;
boolean strata=false;
ImageButton button;
Numberbox inputPULI;
Numberbox inputNapryzenieKV;
RadioButton CheckBoxuvum;
CheckBox P4;
Textlabel Vin;
Button connection;
Button Send;
public void setupUI()
{
cp5 = new ControlP5(this);
PFont fontn = createFont("Times New Roman", 18);
PFont p = createFont("Times New Roman", 18);
ControlFont font=new
ControlFont(p);
cp5.setFont(font);
connection = cp5.addButton("toplug")
.setCaptionLabel("ПУСК")
.setPosition(387, 30)
.setSize(150, 30);
serialPortsList = cp5.addDropdownList("Порт")
.setPosition(130, 30)
.setSize(150, 200)
.setItemHeight(30)
.setBarHeight(30);
PImage[] imgs = {loadImage("button101.png"), loadImage("button102.png"), loadImage("button103.png")};
Send = cp5.addButton("toapply")
//.setCaptionLabel("Apply")
//.setPosition(510, 370)
//.setSize(150, 30);
.setPosition(590, 330)
.setImages(imgs)
.updateSize();
//.lock()
Vin = cp5.addTextlabel("naprazhenie kondencatora")
.setText("Voltage K.V")
.setFont(p)
.setColor(color(#00ffff))
.setPosition(45, 320);
CheckBoxuvum = cp5.addRadioButton("UV/UM")
.setPosition(155, 360)
.setSize(15, 15)
.setColorActive(color(255))
.setItemsPerRow(2)
.setSpacingColumn(85)
.addItem("+", 1)
.addItem("-", 2);
P4 = cp5.addCheckBox("std2")
.setPosition(150, 190)
.setSize(15, 15)
.setItemsPerRow(1)
.setSpacingColumn(30)
.setSpacingRow(20)
.addItem("Check", 2);
inputPULI = cp5.addNumberbox("PUL")
.setLabel("Bullet")
.setPosition(220, 220)
.setSize(80, 30)
.setColorValue(0xffffff00)
.setFont(p)
.setScrollSensitivity(1.1)
.setDirection(Controller.HORIZONTAL)
.setRange(1, 199)
.setValue(3);
Label labelinputPULI = inputPULI.getCaptionLabel();
labelinputPULI.setFont(font);
labelinputPULI.setColor(color(#00ffff));
labelinputPULI.toUpperCase(false);
labelinputPULI.setText("Bullet");
labelinputPULI.align(ControlP5.LEFT_OUTSIDE, CENTER);
labelinputPULI.getStyle().setPaddingLeft(-25);
inputNapryzenieKV = cp5.addNumberbox("NapryzenieKV")
.setLabel("Voltage")
.setPosition(150, 270)
.setSize(80, 30)
.setColorValue(0xffffff00)
.setFont(p)
.setScrollSensitivity(1.1)
.setMin(25)
.setMax(99)
.setMultiplier(0.01)
.setDirection(Controller.HORIZONTAL)
.setValue(25);
Label labelinputNapryzenieKV = inputNapryzenieKV.getCaptionLabel();
labelinputNapryzenieKV.setFont(font);
labelinputNapryzenieKV.setColor(color(#00ffff));
labelinputNapryzenieKV.toUpperCase(false);
labelinputNapryzenieKV.setText("Напряжение");
labelinputNapryzenieKV.align(ControlP5.LEFT_OUTSIDE, CENTER);
labelinputNapryzenieKV.getStyle().setPaddingLeft(-45);
textFont(fontn);
{
// button dimensions
int w = 99;
int h = 25;
// test with generated images
button = new ImageButton(555, 230, w, h,
new PImage[]{
loadImage("0.png"), // off
loadImage("1.png"), // 10
loadImage("2.png"), // 20
loadImage("3.png"), // 30
loadImage("4.png"), // 40
loadImage("5.png"), // 50
loadImage("6.png"), // 60
});
}
}
void mousePressed() {
button.mousePressed(mouseX, mouseY);
println(button.min);
}
// test images to represent loaded state images
PImage getImage(int w, int h, int c) {
PImage img = createImage(w, h, RGB);
java.util.Arrays.fill(img.pixels, c);
img.updatePixels();
return img;
}
// make a custom image button class
class ImageButton {
// minutes is the data it stores
int min = 0;
// images for each state
PImage[] stateImages;
// which image to display
int stateIndex;
// position
int x, y;
// dimensions: width , height
int w, h;
// text to display
String label = "ВЫКЛ";
ImageButton(int x, int y, int w, int h, PImage[] stateImages) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.stateImages = stateImages;
}
void mousePressed(int mx, int my) {
// check the cursor is within the button bounds
boolean isOver = ((mx >= x && mx <= x + w) && // check horizontal
(my >= y && my <= y + h) ); // check vertical
if (isOver) {
min += 10;
stateIndex++;
if (min>60) {
min = 0;
stateIndex = 0;
label = "ВЫКЛ";
} else {
label = (str(min) + "Мин");
}
}
}
void draw() {
// if the images and index are valid
if (stateImages != null && stateIndex < stateImages.length) {
image(stateImages[stateIndex], x, y, w, h);
} else {
println("error displaying button state image");
println("stateImages: ");
printArray(stateImages);
println("stateIndex: " + stateIndex);
}
// display text
//text(label, x + 17, y + h - 8);
}
}
void controlEvent(ControlEvent theEvent) {
if (theEvent.isFrom(CheckBoxuvum)) {
//myColorBackground = 0;
print("got an event from "+CheckBoxuvum.getName()+"\t\n");
// checkbox uses arrayValue to store the state of
// individual checkbox-items. usage:
println(CheckBoxuvum.getArrayValue());
int col = 0;
for (int i=0; i<CheckBoxuvum.getArrayValue().length; i++) {
int n = (int)CheckBoxuvum.getArrayValue()[i];
print(n);
if (n==1) {
//myColorBackground += CheckBoxuvum.getItem(i).internalValue();
}
}
println();
}
if (theEvent.isGroup()) {
// check if the Event was triggered from a ControlGroup
println("event from group : "+theEvent.getGroup().getValue()+" from "+theEvent.getGroup());
} else if (theEvent.isController()) {
println("event from controller : "+theEvent.getController().getValue()+" from "+theEvent.getController());
}
}
Protocol:
int lengthmas = 7;
int RC = 0x21; // -128 separating byte в java
int[] writeOutgioing = new int[lengthmas];
String incomingData= null;
String outgoingData=null;
String[] testRead = new String[lengthmas];
int x;
void readInc() {
while ( serialPort.available() > 0)
{
incomingData = serialPort.readStringUntil(RC);
testRead = split (incomingData, ',' );
if (testRead != null)
{
x = (int) testRead[0].charAt(0);
Displaydata();
}
}
}
void writeOut() {
outgoingData=str(writeOutgioing[0])+str(writeOutgioing[1])+str(writeOutgioing[2])+str(writeOutgioing[3])+str(writeOutgioing[4])+str(writeOutgioing[5])+str(writeOutgioing[6]); // sending data as a string.
serialPort.write(outgoingData);
}
Senddata:
public void toapply()
{
}
loop:
void draw()
{
background(50);
button.draw();
if (strata)
{
readInc();
}
}
code:
inputPULI = cp5.addNumberbox("PUL")
.setLabel("Bullet")
.setPosition(220, 220)
.setSize(80, 30)
.setColorValue(0xffffff00)
.setFont(p)
.setScrollSensitivity(1.1)
.setDirection(Controller.HORIZONTAL)
.setRange(1, 199)
.setValue(3);
Label labelinputPULI = inputPULI.getCaptionLabel();
labelinputPULI.setFont(font);
labelinputPULI.setColor(color(#00ffff));
labelinputPULI.toUpperCase(false);
labelinputPULI.setText("Bullet");
labelinputPULI.align(ControlP5.LEFT_OUTSIDE, CENTER);
labelinputPULI.getStyle().setPaddingLeft(-25);
I figured it out myself, I had to write setLabel->setValueLabel
This question already has answers here:
Thread Sleeping Before GUI Updating (Java 6)
(2 answers)
Closed 6 years ago.
So, the program is for school and i am having some problems, the basic premise is to have to user choose shape, size and colour, then draw the shape or animate it to move across the screen.
My programs works fine without the thread.sleep (it moves across the screen instantly). When i added the thread.sleep it was not working and waited 10 seconds before immediately moving to the end.
After testing around, it seems to have some correlation with the for loop it was in as when the for loop was to 1000 it waited 10 seconds then moved 1000 spaces instantly but when the for loop was 100 it only took one second to move 100 spaces instantly.
My understanding was that it should just wait 10 milliseconds before going into the for loop again.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class AppletAssignemntIsFucked extends Applet
implements ActionListener
{
int colourChoice;
int shapeChoice;
int location;
int x, y;
TextField height = new TextField ("00");
TextField width = new TextField ("00");
boolean animating = false;
//declare the two types of checkboxes
CheckboxGroup shape, colour;
//declare all the shape checkboxes
Checkbox buttonSquare, buttonCircle, buttonRectangle, buttonOval;
//declare all the colour checkboxes
Checkbox buttonRed, buttonBlue, buttonGreen, buttonYellow;
Button buttonDraw, buttonAnimate, buttonReset;
public void init ()
{
setBackground (Color.lightGray);
shape = new CheckboxGroup ();
colour = new CheckboxGroup ();
buttonCircle = new Checkbox ("Circle", shape, true);
add (buttonCircle);
buttonSquare = new Checkbox ("Square", shape, false);
add (buttonSquare);
buttonRectangle = new Checkbox ("Rectangle", shape, false);
add (buttonRectangle);
buttonOval = new Checkbox ("Oval", shape, false);
add (buttonOval);
buttonRed = new Checkbox ("Red", colour, true);
add (buttonRed);
buttonBlue = new Checkbox ("Blue", colour, false);
add (buttonBlue);
buttonGreen = new Checkbox ("Green", colour, false);
add (buttonGreen);
buttonYellow = new Checkbox ("Yellow", colour, false);
add (buttonYellow);
buttonDraw = new Button ("draw");
buttonDraw.addActionListener (this);
add (buttonDraw);
buttonAnimate = new Button ("animate");
buttonAnimate.addActionListener (this);
add (buttonAnimate);
buttonReset = new Button ("reset");
buttonReset.addActionListener (this);
add (buttonReset);
add (height);
add (width);
}
public void paint (Graphics g)
{
switch (colourChoice)
{
case 1:
g.setColor (Color.red);
break;
case 2:
g.setColor (Color.green);
break;
case 3:
g.setColor (Color.yellow);
break;
case 4:
g.setColor (Color.blue);
break;
}
switch (shapeChoice)
{
case 1:
g.fillOval (location, 80, x, x);
break;
case 2:
g.fillRect (location, 80, x, x);
break;
case 3:
g.fillRect (location, 80, x, y);
break;
case 4:
g.fillOval (location, 80, x, y);
break;
}
}
public void actionPerformed (ActionEvent evt)
{
y = Integer.parseInt (height.getText ());
x = Integer.parseInt (width.getText ());
//set the colour
if (evt.getSource () == buttonAnimate)
{
for (int i = 0 ; i < 1000 ; i++)
{
try
{
Thread.sleep (10);
}
catch (InterruptedException ex)
{
Thread.currentThread ().interrupt ();
}
location += 1;
repaint ();
}
}
if (evt.getSource () == buttonReset)
{
location = 10;
repaint ();
}
if (evt.getSource () == buttonDraw)
{
if (buttonRed.getState () == true)
{
colourChoice = 1;
}
else if (buttonGreen.getState () == true)
{
colourChoice = 2;
}
else if (buttonYellow.getState () == true)
{
colourChoice = 3;
}
else if (buttonBlue.getState () == true)
{
colourChoice = 4;
}
//set the shape
if (buttonCircle.getState () == true)
{
shapeChoice = 1;
}
else if (buttonSquare.getState () == true)
{
shapeChoice = 2;
}
else if (buttonRectangle.getState () == true)
{
shapeChoice = 3;
}
else if (buttonOval.getState () == true)
{
shapeChoice = 4;
}
repaint ();
}
}
}
You are blocking the Event Dispatch Thread, so UI cannot get updated.
E.g. see Thread Sleeping Before GUI Updating.
Use a Swing Timer instead.
I am adding JLabel objects to a JPanel. Each label has a different tool tip text that I use to identify each label afterwards, the problem is that the tool tip is always showing on hover and I need it to always be hidden.
Each label has a different image icon that's why I can't use the label text.
I can't find any documentation on the label API for some function like .hidetooltip.
Edit
Each of many JLabel objects on a GridLayout holds an Image. I need to know the line and column of each image.
To hide the tool tip text to null
myComponent.setToolTipText(null);
This is described in the API for this method: "param - the string to display; if the text is null, the tool tip is turned off for this component"
EDIT: In response to your actual issue that you describe in one of your comments, there are a variety of ways association information with a JLabel. You could a) extend the class and keep instance variables defining the grid values b) use a Map key'd with the JLabel and value'd with the row/col c) use the Name of the JLabel
Each of many JLabel objects on a GridLayout holds an Image. I need to know the line and column of each image.
One way to achieve this is to store a BufferedImage[][] to check images against. E.G.
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.net.URL;
import java.util.Random;
import javax.imageio.ImageIO;
public final class ImageArray {
int r = 8;
int c = 8;
// The images in the chess board, used to check which
// image was chosen for this place on the board.
final private BufferedImage[][] chessBoardImages = new BufferedImage[r][c];
private final int rowSprite = 2;
private final int colSprite = 6;
// Holds the tile sheet images
private final BufferedImage[] chessPieceImages =
new BufferedImage[colSprite * rowSprite];
private JComponent ui = null;
private final BufferedImage chessSpriteSheet;
ImageArray(BufferedImage chessSpriteSheet) {
this.chessSpriteSheet = chessSpriteSheet;
initUI();
}
private int getImageIndex(Image img) {
for (int i = 0; i < chessPieceImages.length; i++) {
if (chessPieceImages[i].equals(img)) {
return i;
}
}
return -1;
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
int w = chessSpriteSheet.getWidth();
int h = chessSpriteSheet.getHeight() / rowSprite;
int wStep = chessSpriteSheet.getWidth() / colSprite;
int hStep = chessSpriteSheet.getHeight() / rowSprite;
for (int x = 0; x < colSprite; x++) {
for (int y = 0; y < rowSprite; y++) {
chessPieceImages[x + (y * colSprite)]
= chessSpriteSheet.getSubimage(
x * wStep, y * hStep, wStep, h);
}
}
JPanel grid = new JPanel(new GridLayout(r, c));
ui.add(grid, BorderLayout.CENTER);
Random rand = new Random();
for (int x = 0; x < r; x++) {
boolean oddRow = x % 2 == 0;
for (int y = 0; y < c; y++) {
boolean oddCol = y % 2 == 0;
BufferedImage img = chessPieceImages[
rand.nextInt(colSprite * rowSprite)];
JLabel l = new JLabel(new ImageIcon(img));
chessBoardImages[x][y] = img;
l.setOpaque(true);
if ((oddRow && oddCol) || (!oddRow && !oddCol)) {
l.setBackground(Color.WHITE);
} else {
l.setBackground(Color.LIGHT_GRAY);
}
grid.add(l);
}
}
JLabel htmlLabel = new JLabel(getHtml());
htmlLabel.setHorizontalTextPosition(SwingConstants.CENTER);
htmlLabel.setVerticalTextPosition(SwingConstants.BOTTOM);
ui.add(htmlLabel,
BorderLayout.LINE_END);
}
private String getHtml() {
String style = "<style type='text/css'>"
+ "body {"
+ "font-size: 36px;"
+ "}"
+ ".white {"
+ "background-color: #FFFFFF;"
+ "}"
+ ".black {"
+ "background-color: #BBBBBB;"
+ "}"
+ "</style>";
String pre = "<html><head>%1s</head><body><table border=1 cellspacing=0>";
StringBuilder sb = new StringBuilder(String.format(pre, style));
for (int y = 0; y < r; y++) {
sb.append("<tr>");
for (int x = 0; x < c; x++) {
Image img = chessBoardImages[y][x];
final int index = getImageIndex(img);
// hack to convert index to unicode codepoint..
int unicodeOffset = ((index/colSprite)*colSprite)==0 ? colSprite : -colSprite;
int unicodeIndexOffset;
switch (index) {
case 3:
unicodeIndexOffset = 4;
break;
case 4:
unicodeIndexOffset = 3;
break;
case 9:
unicodeIndexOffset = 10;
break;
case 10:
unicodeIndexOffset = 9;
break;
default:
unicodeIndexOffset = index;
}
int unicode = 9812 + unicodeIndexOffset + unicodeOffset;
// end: hack to convert index to unicode index..
String cssClass;
boolean oddCol = x%2==1;
boolean oddRow = y%2==1;
if ((oddRow && oddCol) || (!oddRow && !oddCol)) {
cssClass = "white";
} else {
cssClass = "black";
}
sb.append(String.format(
"<td class='%1s'>&#%2s;</td>", cssClass, unicode));
}
sb.append("</tr>");
}
sb.append("</table></body></html>");
return sb.toString();
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) throws Exception {
String urlString = "http://i.stack.imgur.com/memI0.png";
final BufferedImage img = ImageIO.read(new URL(urlString));
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
ImageArray o = new ImageArray(img);
JFrame f = new JFrame("Image Array");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
You should consider storing the information elsewhere. One way would be to make a class deriving from JLabel with the purpose of storing the line and column information. Then use instances of this subclass rather than use JLabel instances. They will render as a regular JLabel would, but you can retrieve the line and column information in a way that does not pop up that information in a tooltip.
I couldn't find any other solutions to my problem because I'm unsure of how to describe it in few enough words.
When I assign activeList, which is a field of currentActiveList a randomly generated Rectangle in the ActiveList class it receives the value just fine.
public class ActiveList {
Rectangle[] activeList = new Rectangle[10];
public ActiveList() {
for(int i = 0; i < activeList.length; i++)
activeList[i] = null;
}
public void addToList(Rectangle x) {
for(int i = 0; i < this.activeList.length; i++) {
if(this.activeList[i] == null) {
this.activeList[i] = x;
i = this.activeList.length+1;
}
else
this.activeList[activeList.length-1] = x;
}
}
public Rectangle[] getActiveList() {
return this.activeList;
}
public int getLength() {
//System.out.print(this.activeList.length);
return this.activeList.length;
}
public void deleteFromList(int x) {
this.activeList[x] = null;
}
public Rectangle getFromList(int x) {
Rectangle retVal = this.activeList[x];
//System.out.println("Returning getFromList(int x): " +retVal);
return retVal;
}
public void genRandomRectangle() {
Random randomNumberGenerator = new Random();
double[] pointVal = new double[4];
double randomInt = randomNumberGenerator.nextInt(400-10);
pointVal[0] = randomInt;
randomInt = randomNumberGenerator.nextInt(400-10);
pointVal[1] = randomInt;
randomInt = randomNumberGenerator.nextInt((int) (400-pointVal[0]));
if(randomInt < 5) {
randomInt = randomInt+pointVal[0]+5;
}
else
pointVal[2] = randomInt+pointVal[0];
randomInt = randomNumberGenerator.nextInt((int) (400-pointVal[1]));
if(randomInt < 5) {
randomInt = randomInt+pointVal[1]+5;
}
else
pointVal[3] = randomInt+pointVal[1];
Rectangle newRandom = new Rectangle(pointVal[0], pointVal[1], pointVal[2], pointVal[3]);
//System.out.println(pointVal[0]);
//System.out.println(pointVal[1]);
//System.out.println(pointVal[2]);
//System.out.println(pointVal[3]);
System.out.println("New Random: " +newRandom);
addToList(newRandom);
}
}
However, when I try to use those values in my main class GraphicGen, the currentActiveList returns null values for all of its indexes.
public class GraphicGen extends JPanel {
ActiveList currentActiveList = new ActiveList();
public static int gridSpaceX = 400;
public static int gridSpaceY = 400;
static JFrame mainFrame = new JFrame();
protected void paintComponent(Graphics g) {
//super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//int w = getWidth();
//int h = getHeight();
// Draw ordinate.
//g2.draw(new Line2D.Double(PAD, PAD, PAD, h-PAD));
// Draw abcissa.
//g2.draw(new Line2D.Double(PAD, h-PAD, w-PAD, h-PAD));
//double xInc = (double)(w - 2*PAD)/(data.length-1);
//double scale = (double)(h - 2*PAD)/maxValue();
// Mark data points.
//g2.setPaint(Color.red);
double[] coords = new double[4];
//g2.fill(new Ellipse2D.Double(coords[0], coords[1], 4, 4));
//g2.fill(new Ellipse2D.Double(coords[2], coords[3], 4, 4));
//g2.fill(new Ellipse2D.Double(100, 100, 4, 4));
System.out.println("Graphic Gen Active List Obj: " +currentActiveList);
System.out.println("Ya drew a new Main GUI!");
System.out.println("currentActiveList.getActiveList(): " +currentActiveList.getActiveList());
for(int i = 0; i < currentActiveList.getLength(); i++) {
//System.out.println("currentActiveList.getFromList(i): "+currentActiveList.getFromList(i));
//System.out.println("Graphic Gen Active List Obj: " +currentActiveList);
//System.out.println(activeList.getFromList(i).getTopLeftX());
if(currentActiveList.getFromList(i) != null) {
coords[0] = currentActiveList.getFromList(i).getTopLeftX();
System.out.println(coords[0]);
coords[1] = currentActiveList.getFromList(i).getTopLeftY();
System.out.println(coords[1]);
coords[2] = currentActiveList.getFromList(i).getBottomRightX();
System.out.println(coords[2]);
coords[3] = currentActiveList.getFromList(i).getBottomRightY();
System.out.println(coords[3]);
g2.draw(new Line2D.Double(coords[0], coords[1], coords[2], coords[1]));
g2.draw(new Line2D.Double(coords[0], coords[1], coords[0], coords[3]));
g2.draw(new Line2D.Double(coords[2], coords[1], coords[2], coords[3]));
g2.draw(new Line2D.Double(coords[0], coords[3], coords[2], coords[3]));
}
}
/*double x = 50;
double y = 50;
g2.fill(new Ellipse2D.Double(x, y, 4, 4));*/
/*for(int i = 0; i < data.length; i++) {
double x = PAD + i*xInc;
double y = h - PAD - scale*data[i];
g2.fill(new Ellipse2D.Double(x-2, y-2, 4, 4));
}*/
}
/*private int maxValue() {
int max = data[0];
for(int i = 0; i < data.length; i++) {
if(data[i] > max)
max = data[i];
}
return max;
}*/
public void callRepaintOnMain() {
mainFrame.repaint();
}
public void callGenRandom() {
currentActiveList.genRandomRectangle();
}
public static void main(String[] args) {
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.add(new GraphicGen());
mainFrame.setSize(gridSpaceX, gridSpaceY);
ButtonPrompt buttonPrompter = new ButtonPrompt();
mainFrame.setLocation(200,200);
mainFrame.setVisible(true);
}
}
The random generator method is called by the action listener.
public class ButtonPrompt extends GraphicGen {
ActionListener actionListenerRandom = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
//currentActiveList.genRandomRectangle();
callGenRandom();
callRepaintOnMain();
}
};
JButton randomBtn = new JButton("Add Random Rectangle");
JButton inputCoordinates = new JButton("Input Rectangle Coordinates");
public ButtonPrompt() {
JFrame f = new JFrame("Add Rectangles");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BoxLayout boxLayout = new BoxLayout(f.getContentPane(), BoxLayout.Y_AXIS);
f.setLayout(boxLayout);
randomBtn.addActionListener(actionListenerRandom);
f.setSize(200, 200);
f.setLocation(600, 200);
f.setVisible(true);
f.add(randomBtn);
f.add(inputCoordinates);
f.pack();
}
}
Is this a scoping or referencing problem? I'm really at a loss here.
Here:
public static void main(String[] args) {
...
mainFrame.add(new GraphicGen());
...
ButtonPrompt buttonPrompter = new ButtonPrompt();
}
ButtonPrompt extends GraphicGen, which is a JPanel. In ButtonPrompt's constructor, you created a JFrame and added two JButtons to it.
So when your app starts, there will be two JFrames on the screen, one is mainFrame which contains a GraphicGen, the other is buttonPrompter which contains two buttons.
When you click on the button, the actionPerformed() is called and it's actually calling the callGenRandom() of the buttonPrompter -- if the random generation logic is correct, the generated Rectangles are added to buttonPrompter. But you didn't add this buttonPrompter to any one of the JFrames, you won't see it.
What you may want:
ButtonPrompt doesn't extend GraphicGen, instead, give ButtonPrompt a reference of the GraphicGen you added to the mainFrame.
public class ButtonPrompt extends GraphicGen {
JButton randomBtn = new JButton("Add Random Rectangle");
JButton inputCoordinates = new JButton("Input Rectangle Coordinates");
final GraphicGen gg;
public ButtonPrompt(GraphicGen gg) {
this.gg = gg;
......
ActionListener actionListenerRandom = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
gg.callGenRandom();
gg.callRepaintOnMain();
}
};
randomBtn.addActionListener(actionListenerRandom);
......
}
}
and in your main():
public static void main(String[] args) {
...
GraphicGen gg = new GraphicGen();
mainFrame.add(gg);
...
ButtonPrompt buttonPrompter = new ButtonPrompt(gg);
}
What's more, the code has other problems.
For example, GraphicGen is a JPanel, main class and it has a field of a JFrame which actually contains the GraphicGen instance when app runs -- this looks bad. I don't know much of Swing... Is it a must to call the containing JFrame's repaint() instead of just calling the JPanel's repaint(), if it has?
Your actual problem is quite unclear, but just reading the first two methods is enough to find what, I suppose, is a bug:
public ActiveList() {
for(int i = 0; i < activeList.length; i++)
activeList[i] = null;
}
the above code is completely useless. The default value of an element of an array of objects is null. So the loop assigns null to a variable wich is already null.
public void addToList(Rectangle x) {
for(int i = 0; i < this.activeList.length; i++) {
if(this.activeList[i] == null) {
this.activeList[i] = x;
i = this.activeList.length+1;
}
else
this.activeList[activeList.length-1] = x;
}
}
If your list only contains null, the rectangle will be stored at index 0, and the loop will stop. For all the susequent calls to this method, the loop will find that the element at index 0 is not null, and will thus store x at the last index of the array, and then at the first non-null index.
I don't know exactly what you're trying to achieve, and what the actual problem is, but you should probably forget about implementing your own list based on an array, and use an ArrayList instead.
I need help tweaking my code. I need to write a program that outputs the count of individual ascii characters in a txt file that the user uploads, but I'm having a lot of problems trying to get the array that I count into the GUI portion of the program that "draws" the data on the screen.
I have the output looking how I want, but I can't figure out how to get the character count up there
I want to put the number of times a character/punction/number is used in a file that the user uploads on a graphic display. For instance, 33 or ! there are 3 instances. Or 65 A there are 4354 instances in the file. However I'm having a large problem with getting the counter to count the characters in the word correctly, and even more trouble getting the stored array of numbers of characters to the GUI (g.draw) section of the program.
Instead of a number, I just get a blank output column.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.FileReader; // both needed
import java.io.BufferedReader;
import java.io.IOException;
public class textreader extends Frame implements ActionListener
{
String dataFilePath = null;
String dataFileName = null;
int[] counter = new int[256];
String command = "";
public static void main(String[] args)
{
Frame frame = new textreader();
frame.setResizable(true);
frame.setSize(1000,850);
frame.setVisible(true);
}
public textreader()
{
setTitle("Text File Processing");
// Menu Creation
MenuBar mn = new MenuBar();
setMenuBar(mn);
// Create "File" and add it
Menu fileMenu = new Menu("File");
mn.add(fileMenu);
// Create Menu Items, Add action Listener, Add to "File" Menu Group
// Open file
MenuItem miOpen = new MenuItem("Open");
miOpen.addActionListener(this);
fileMenu.add(miOpen);
// Process file
MenuItem miProcess = new MenuItem("Process");
miProcess.addActionListener(this);
fileMenu.add(miProcess);
// Exit program
MenuItem miExit = new MenuItem("Exit");
miExit.addActionListener(this);
fileMenu.add(miExit);
// To Terminate
WindowListener d = new WindowAdapter()
{
public void windowClosing(WindowEvent ev)
{
System.exit(0);
}
public void windowActivated(WindowEvent ev)
{
repaint();
}
public void windowStateChanged(WindowEvent ev)
{
repaint();
}
};
ComponentListener k = new ComponentAdapter()
{
public void componentResized(ComponentEvent e)
{
repaint();
}
};
// listener registry
this.addWindowListener(d);
this.addComponentListener(k);
}
public void actionPerformed (ActionEvent ev)
{
// which command was issued?
command = ev.getActionCommand();
// act
if("Open".equals(command))
{
dataFilePath = null;
dataFileName = null;
JFileChooser chooser = new JFileChooser();
chooser.setDialogType(JFileChooser.OPEN_DIALOG );
chooser.setDialogTitle("Open Data File");
int returnVal = chooser.showOpenDialog(null);
if( returnVal == JFileChooser.APPROVE_OPTION)
{
dataFilePath = chooser.getSelectedFile().getPath();
dataFileName = chooser.getSelectedFile().getName();
}
repaint();
}
else
if("Process".equals(command))
{
try
{
// Initialize
int[] aCount = new int[256];
// "Instantiate" streams
BufferedReader inputStream = new BufferedReader(new FileReader(dataFilePath));
// read the file line by line and count the characters read
String line = null;
char c = 0;
int lineLength = 0;
int charValue = 0;
while ((line = inputStream.readLine()) != null)
{
// ********* process line
for (int i = 0; i < line.length(); i++)
{
char ch = line.charAt(i);
if (ch >= 0 && ch <= 255)
{
counter[(int)ch]++;
}
else
{ // silently ignore non-ASCII characters
}
// count newline at the end
counter['\n']++;
}
}
}
catch(IOException ioe)
{
System.out.print("You want to run that by me again?");
}
repaint();
}
else
if("Exit".equals(command))
{
System.exit(0);
}
}
//********************************************************
//called by repaint() to redraw the screen
//********************************************************
public void paint(Graphics g)
{
if("Open".equals(command))
{
// Acknowledge that file was opened
if (dataFileName != null)
{
g.drawString("File -- "+dataFileName+" -- was successfully opened", 400, 400);
}
else
{
g.drawString("NO File is Open", 400, 400);
}
return;
}
else
if("Process".equals(command))
{
for(int i = 0; i < 256; i++)
{
int x = 100;
int y = 100;
g.drawString("Int", x, y);
g.drawString("Char", x+50, y);
g.drawString("Count", x+100, y);
g.drawLine(100, y+15, x+120, y+15);
y = y + 30;
int line = 0;
for(int j = 0; j < 256; j++)
{
line++;
g.drawString(Integer.toString(j), x, y);
g.drawString(Character.toString((char)j), x + 50, y);
// Converts the # to a char, then to a String
// This part of the code adds a new column when the flag reaches 43
if(line == 45)
{
x = x + 150;
y = 100;
g.drawString("Int", x, y);
g.drawString("Char", x+50, y);
g.drawString("Count", x+100, y);
g.drawLine(100, y+15, x+120, y+15);
y = y + 15;
line = 0;
}
y = y+15;
}
}
return;
}
}
}
just add this to your code:
g.drawString(Integer.toString(counter[j]), x + 120, y);
right here (int the paint method):
g.drawString(Integer.toString(j), x, y);
g.drawString(Character.toString((char)j), x + 50, y);
g.drawString(Integer.toString(counter[j]), x + 120, y);