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);
Related
I'm making a chess program for a school project using swing. this is my first time using swing however I've had a lot of experience with tkinter in python which feels similar. I've gotten the pieces loaded onto board and can load in FEN strings.
The basic board when loaded in
Now I've been trying to move on to allowing the player to capture other pieces. currently I'm not worried about the rules of how pieces can move and I'm just trying to allow them to capture anything.
A little bit of extra knowledge that may be useful is that I have two 2d arrays for the board. one contains a 2d array of 64 buttons (one for each square). the other contains a 2d int array and contains the numerical value of each piece in each square.
the following code is my code for attempting to capture pieces. My thinking behind this implementation is to first find when we select a piece that we want to move. when we click on this piece we store it in selected and set isSelecting equal to true. then the next piece we click on we should capture. The way I've been trying to tackle this is by finding the square we want to capture and changing the piece icon to the icon of the piece we stored in selected. then setting the selected pieces icon to a empty icon. then doing the same for the int array.
public boolean isSelecting;
public JButton selected;
public int[] findSpot(JButton but){
for (int i = 0 ; i < board.length; i++)
for (int j = 0 ; j < board.length; j++)
{
if ( board[i][j] == but)
{
return new int[]{i,j};
}
}
return new int[]{-1,-1};
}
#Override
public void mouseReleased(MouseEvent e) {
System.out.println(1);
System.out.println(isSelecting);
if (!isSelecting) {
System.out.println(2);
selected = (JButton) e.getSource();
System.out.println(e.getSource());
} else {
System.out.println(3);
int[] temp = findSpot(selected);
ImageIcon i = new ImageIcon(pieceFiles.get(intBoard[temp[0]][temp[1]]));
Image img = i.getImage() ;
Image newimg = img.getScaledInstance(75, 75, java.awt.Image.SCALE_SMOOTH ) ;
i = new ImageIcon( newimg );
((JButton) e.getSource()).setIcon(i);
int[]temp2 = findSpot(((JButton) e.getSource()));
intBoard[temp[0]][temp[1]] = intBoard[temp2[0]][temp2[1]];
selected.setIcon(new ImageIcon());
intBoard[temp[0]][temp[1]] = none;
selected = null;
}
isSelecting = !isSelecting;
}
This code, however, isn't working and I can't figure out why. The specific problem is the isSelecting variable on becomes false when you click the same piece twice. Clicking two separate pieces does nothing however clicking the same piece twice removes said piece.
The output after clicking the first three pawns
The output after clicking those three pawns for a second time
I'm going to leave my full code here. I'm not sure if I should since it's long but I hope it can give you a better scope of the project.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Hashtable;
import javax.swing.*;
public class Chess implements MouseListener {
static int none = 0;
static int king = 1;
static int pawn = 2;
static int knight = 3;
static int bishop = 4;
static int rook = 5;
static int queen = 6;
static int black = 8;
static int white = 16;
public boolean isSelecting;
public JButton selected;
static JButton[][] board = new JButton[8][8];
static int[][] intBoard = new int[8][8];
static JFrame frame = new JFrame("Big Willy's Chess");
static Hashtable<Integer, String> pieceFiles = new Hashtable<>();
public static void cTable() {
String folder = "C:\\Users\\bookr\\IdeaProjects\\CSA\\src\\pieces";
pieceFiles.put(king + black, folder + "\\Chess_kdt60.png");
pieceFiles.put(king + white, folder + "\\Chess_klt60.png");
pieceFiles.put(pawn + black, folder + "\\Chess_pdt60.png");
pieceFiles.put(pawn + white, folder + "\\Chess_plt60.png");
pieceFiles.put(knight + black, folder + "\\Chess_ndt60.png");
pieceFiles.put(knight + white, folder + "\\Chess_nlt60.png");
pieceFiles.put(bishop + black, folder + "\\Chess_bdt60.png");
pieceFiles.put(bishop + white, folder + "\\Chess_blt60.png");
pieceFiles.put(rook + black, folder + "\\Chess_rdt60.png");
pieceFiles.put(rook + white, folder + "\\Chess_rlt60.png");
pieceFiles.put(queen + black, folder + "\\Chess_qdt60.png");
pieceFiles.put(queen + white, folder + "\\Chess_qlt60.png");
}
public static boolean isNumeric(String str) {
try {
Double.parseDouble(str);
return true;
} catch(NumberFormatException e) {
return false;
}
}
public static void loadFenPos(String fen){
Hashtable<String, Integer> pieceNumbs = new Hashtable<>();
pieceNumbs.put("k", king);
pieceNumbs.put("p", pawn);
pieceNumbs.put("n", knight);
pieceNumbs.put("b", bishop);
pieceNumbs.put("r", rook);
pieceNumbs.put("q", queen);
int rank = 0;
int file = 0;
for (String symbol:fen.split("")) {
if (symbol.equals("/")) {
file = 0;
rank++;
}
else {
if (!isNumeric(symbol)) {
int pieceColor = Character.isUpperCase(symbol.charAt(0)) ? white : black;
int pieceType = pieceNumbs.get(symbol.toLowerCase());
ImageIcon i = new ImageIcon(pieceFiles.get(pieceType+pieceColor));
Image img = i.getImage();
Image newimg = img.getScaledInstance(75, 75, java.awt.Image.SCALE_SMOOTH);
i = new ImageIcon(newimg);
intBoard[rank][file] = pieceType+pieceColor;
board[rank][file].setIcon(i);
file++;
} else {
file += Integer.parseInt(symbol);
}
}
}
}
public void start (){
cTable();
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(8, 8));
Color lightSquareColor = new Color(240, 240, 240);
Color darkSquareColor = new Color(128, 128, 128);
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 8; col++) {
JButton button = new JButton();
button.setOpaque(true);
button.setBorderPainted(false);
button.setFocusPainted(false);
if ((row + col) % 2 == 0) {
button.setBackground(lightSquareColor);
} else {
button.setBackground(darkSquareColor);
}
button.addMouseListener(new Chess());
panel.add(button);
board[row][col] = button;
}
}
// ImageIcon i = new ImageIcon("C:\\Users\\bookr\\IdeaProjects\\CSA\\src\\pawn.png");
//
//
// Image img = i.getImage() ;
// Image newimg = img.getScaledInstance(75, 75, java.awt.Image.SCALE_SMOOTH ) ;
// i = new ImageIcon( newimg );
// board[6][7].setIcon(i);
loadFenPos("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR");
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setSize(600, 600);
frame.setVisible(true);
}
public static void main(String[] args) {
Chess game = new Chess();
game.start();
}
public int[] findSpot(JButton but) {
for (int i = 0 ; i < board.length; i++)
for(int j = 0 ; j < board.length; j++)
{
if ( board[i][j] == but)
{
return new int[]{i,j};
}
}
return new int[]{-1,-1};
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
System.out.println(1);
System.out.println(isSelecting);
if (!isSelecting) {
System.out.println(2);
selected = (JButton) e.getSource();
} else {
System.out.println(3);
int[] temp = findSpot(selected);
ImageIcon i = new ImageIcon(pieceFiles.get(intBoard[temp[0]][temp[1]]));
Image img = i.getImage() ;
Image newimg = img.getScaledInstance(75, 75, java.awt.Image.SCALE_SMOOTH ) ;
i = new ImageIcon( newimg );
((JButton) e.getSource()).setIcon(i);
int[]temp2 = findSpot(((JButton) e.getSource()));
intBoard[temp[0]][temp[1]] = intBoard[temp2[0]][temp2[1]];
selected.setIcon(new ImageIcon());
intBoard[temp[0]][temp[1]] = none;
selected = null;
}
isSelecting = !isSelecting;
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
I've tried messing changing around the isSelecting variable, how I assign the selected variable, and how I update the 2d arrays.
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
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.
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.
Trying to get the final part of this game to work. Its a hangman game, I just need it to display correct guesses where they are in the word.
This is the snippet of code of when a correct guess is given
else
{
int alreadyGuessed = guesses.indexOf(guess);
if (alreadyGuessed == -1)
{
guesses = guesses + guess + "";
jlbWord.setText("Word: " + charWord[currentGuess]);
}
else{}
}
Right now it simply shows each letter. I can also set it, so it shows each one as they are typed in but its not in the right order, which makes it much more difficult for the user to guess what the word is.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.Dimension;
public class RightPanel extends JPanel implements KeyListener
{
JLabel jlbMissed, jlbWord, jlbTimer;
Color btnColor;
JComboBox jcbDifficulty;
JButton jbtStart, jbtQuit;
String[] difficulties = {"Easy", "Medium", "Hard"};
String[] words = {"First", "Next", "Hello", "World"};
char guess;
String word, guesses = "";
char[] charWord;
public static int incorrectGuesses = 0;
boolean clockIsRunning = false;
boolean gameInPlay = false;
int sec = 0;
int min = 0;
public RightPanel()
{
this.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
Random ran = new Random(); //
int rand = ran.nextInt(4); // Generates random number then selects word from words array
word = words[rand]; //
charWord = word.toCharArray();
ActionHandler actionHandler = new ActionHandler();
jlbMissed = new JLabel("Missed: ");
jlbWord = new JLabel("Word: ");
jlbTimer = new JLabel("Time: " + "0:00");
jbtStart = new JButton("Start");
jbtQuit = new JButton("Quit");
jcbDifficulty = new JComboBox();
jbtStart.addActionListener(actionHandler);
jbtQuit.addActionListener(actionHandler);
jcbDifficulty.addKeyListener(this);
jbtStart.addKeyListener(this);
for (int i = 0; i < 3; i++)
{
jcbDifficulty.addItem(difficulties[i]); // Creates Difficutly ComboBox
}
this.add(jcbDifficulty, getConstraints(0,0,1,1, GridBagConstraints.WEST));
this.add(jlbMissed, getConstraints(0,1,1,1, GridBagConstraints.WEST));
this.add(jlbWord, getConstraints(0,2,1,1, GridBagConstraints.WEST));
this.add(jlbTimer, getConstraints(0,4,1,1, GridBagConstraints.WEST));
this.add(jbtStart, getConstraints(0,6,1,1, GridBagConstraints.WEST));
this.add(jbtQuit, getConstraints(0,7,1,1, GridBagConstraints.WEST));
}
public void keyPressed(KeyEvent e){}
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e)
{
guess = e.getKeyChar();
if (gameInPlay == false)
{
JOptionPane.showMessageDialog(this, "You have not started the game yet!", "Game has not Started", JOptionPane.ERROR_MESSAGE);
System.out.println("Game Not in Play");
}
else
{
if (Character.isLetter(guess))
{
if (incorrectGuesses > 11)
{
clockIsRunning = false;
gameInPlay = false;
JOptionPane.showMessageDialog(this, "You Killed Him! \nThe word was " + word, "He Ceases to Exist", JOptionPane.ERROR_MESSAGE);
jbtStart.setText("Retry?");
jbtStart.setBackground(Color.RED);
}
else
{
int currentGuess = word.indexOf(guess);
if (currentGuess == -1)
{
int alreadyGuessed = guesses.indexOf(guess);
if (alreadyGuessed == -1)
{
guesses = guesses + guess + "";
System.out.println(alreadyGuessed);
System.out.println(guesses);
String temp = jlbMissed.getText();
jlbMissed.setText(temp + guess + ", ");
incorrectGuesses++;
leftPanel.hangmanPic.setIcon(leftPanel.image[RightPanel.incorrectGuesses]);
}
else {}
}
else
{
int alreadyGuessed = guesses.indexOf(guess);
if (alreadyGuessed == -1)
{
guesses = guesses + guess + "";
jlbWord.setText("Word: " + charWord[currentGuess]);
}
else{}
}
}
}
else
JOptionPane.showMessageDialog(this, "That is not a valid guess!\n Please enter a character from A-Z", "Invalid Guess", JOptionPane.ERROR_MESSAGE);
}
}
private GridBagConstraints getConstraints(int gridx, int gridy, int gridwidth, int gridheight, int anchor)
{
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(5,5,5,5);
c.ipadx = 0;
c.ipady = 0;
c.gridx = gridx;
c.gridy = gridy;
c.gridwidth = gridwidth;
c.gridheight = gridheight;
c.anchor = anchor;
return c;
}
class ActionHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
Object source = e.getSource();
if (source == jbtStart)
{
if (clockIsRunning == true){}
else
{
if (jbtStart.getText() == "Start")
{
btnColor = jbtStart.getBackground();
clockIsRunning = true;
MyTimer timer = new MyTimer();
timer.start();
gameInPlay = true;
}
else if (jbtStart.getText() == "Retry?")
{
jbtStart.setText("Start");
jbtStart.setBackground(btnColor);
jlbTimer.setText("Time: " + "0:00");
sec = 0;
min = 0;
MyTimer timer = new MyTimer();
timer.start();
clockIsRunning = true;
gameInPlay = true;
incorrectGuesses = 0;
guesses = "";
jlbMissed.setText("Missed: ");
jlbWord.setText("Word: ");
leftPanel.hangmanPic.setIcon(leftPanel.image[RightPanel.incorrectGuesses]);
Random ran = new Random();
int rand = ran.nextInt(4);
word = words[rand];
}
}
}
else if (source == jbtQuit)
{
System.exit(0);
}
}
}
class MyTimer extends Thread
{
public void run()
{
while(true)
{
if(!clockIsRunning)
break;
try
{
Thread.sleep(1000);
}
catch (InterruptedException ecp)
{
}
if (sec == 59)
{
min++;
sec = 0;
}
else
sec++;
if(sec < 10)
jlbTimer.setText("Time:" + min+":0"+sec);
else
jlbTimer.setText("Time:" + min+":"+sec);
}
}
}
}
Yikes.
You should refactor your code and keep the guesses in a TreeSet<Character> data structure. It assures, that each character is stored only once and that an iterator returns all stored chars in ascending order.
Snippet:
Set<Character> guesses = new HashSet<Character>();
// add a guess
guesses.add('e');
guesses.add('r');
guesses.add('a');
guesses.add('e'); // will not be added, already in the set
// test
if (guesses.contains('e')) { ... }
// test if a word is "guessed"
boolean foundIt = true;
for (char c:word.toCharArray()) {
if (!guesses.contains(c)) {
foundIt = false;
break;
}
}
// foundIt is true if all chars of word have been guessed
// print
for (char c:guesses)
System.out.print(c); // prints: aer