java data structure to hold many arrays of ints and their labels - java

I have input like this:
0, 0, 0, 0, 1, 0, 2, A
0, 0, 3, 0, 1, 0, 2, A
0, 2, 0, 0, 1, 0, 2, B
0, 0, 0, 0, 1, 0, 2, A
With the letter being the label, and then numbers being the inputs.
I'd like to store this whole matrix in one data structure, such that the inputs that correspond to a particular label can be associated with it.
How to do this?
With a 2d array?
With an array list?
Hashmap?

If you want to use A, B,... as keys, than you can use a HashMap with string as keys and arraylist as values
Map<String, List<String>> map = new HashMap<String, List<String>>();
Then you can iterate over your input and check if the map already contains the key.
for (...) {
...
if (!map.containsKey(key)) {
map.put(key, new ArrayList<String>());
}
map.get(key).add(value);
}
This is a generic example and you can do modifications based on your requirements.

If you need your int array just replace the following code:
import java.util.ArrayList;
class Group {
public String key;
public String value;
public String getKey() {
return key;
}
public String getValue() {
return value;
}
Group(String v, String k) {
this.key = k;
this.value = v;
}
#Override
public String toString() {
return this.key + " " + this.value;
}
}
public class Datastructure {
public static void main(String[] args) {
ArrayList<Group> list = new ArrayList<>();
list.add(new Group("0, 0, 0, 0, 1, 0, 2", "A"));
list.add(new Group("0, 0, 3, 0, 1, 0, 2", "A"));
list.add(new Group("0, 2, 0, 0, 1, 0, 2", "B"));
list.add(new Group("0, 0, 0, 0, 1, 0, 2", "A"));
findKeyList(list, "A");
}
public static void findKeyList(ArrayList<Group> list, String search) {
if (!list.isEmpty()) {
for (Group element : list) {
if (element.getKey().equals(search)) {
System.out.println(element.toString());
}
}
}
}
}

HashMap is not a good solution for your case since there is no uniqueness in any of the attributes. Create a classwith 2 attributes:
Class Obj {
char[] array;
String label;
}
Then maintain a list of these objects as ArrayList

You can use a HashMap :
Map<char, String[][]> matrix = new HashMap<char, String[]>();
matrix.put('A', new String[][]{{0, 0, 0, 0, 1, 0, 2}, {0, 0, 3, 0, 1, 0, 2}, ...});
......
This way, many arrays could be associated with a single label (or character).

Related

Read a parameter in at a specific index in arraylist

I have a arraylist with 6 parameters, I wonder how to read one specific parameter with a getter from an other class.
I tried to use .indexOf of an .get from an instance of the arraylist. The variable in the other class is currentRoom = getKarta().get(roomNumber). roomNumber is set to 0 to represent the first room (the first index). What i am trying to do is to read the value from parameter n,s,ö and v with a switch. In the switch i have tried, and failed, to have the if read if n value is bigger than -1, assign that value to roomNumber.
Rum has parameters (String namn, String beskrivning, Integer n, Integer s,Integer ö, Integer v) and is in a separate class.
while(true){
System.out.print("" +currentRoom);
String sInput = input.nextLine();
switch (sInput)
case "n"
if(parameter3 >0) {
rooms´Number = parameter3;
}else {
System.out.println("you cant go north)}
break;
public DragonTreasure() {
karta = new ArrayList<Rum>();
So in the arraylist the values are for: namn, beskrivning, n,s,ö,v.
karta.add(new Rum("Entre", "Rummet är upplyst av några ljus som sitter på ett bord framför dig.", 1, 4, -1, -1));
karta.add(new Rum("Död Kropp", "Du ser en död kropp på golvet.", -1, 0, 2, -1));
karta.add(new Rum("Fackelrum", "Du ser en brinnande fackla i rummets ena hörn och känner en motbjudande stank.", -1, -1, 6, 1));
karta.add(new Rum("Fuktigt Rum", "Du kommer in i ett fuktigt rum med vatten sipprandes längs den västra väggen.", 2, -1, 5, 4));
karta.add(new Rum("Bergsrum", "Du kommer in i ett rymligt bergrum med en ljusstrimma sipprandes genom en spricka i den östra väggen.", 0, -1, 3, -1));
karta.add(new Rum("Låst Rum", "Du har ingen nyckel som passar.", -1, -1, -1, 3));
karta.add(new Rum("Utgång", "Du lämnar grottan med livet i behåll. Grattis, du förlorade inte!", -1, -1, -1, 2));
so for example in Rum at index zero i want to read 1 when asking for n value
It's simple.
1st you need to add a getter in Rum class as follows.
public Integer getN() {
return n;
}
Then in the caller class, you need to call that getter.
public static void main(String[] args) {
ArrayList<Rum> r = DragonTreasure();
System.out.print(r.get(0).getN());
}
I'll add following complete solution for your convenience.
import java.util.ArrayList;
class HelloWorld {
public static void main(String[] args) {
ArrayList<Rum> r = DragonTreasure();
//GETTING THE VALUE OF N
System.out.print(r.get(0).getN());
}
public static ArrayList<Rum> DragonTreasure() {
ArrayList<Rum> karta = new ArrayList<>();
karta.add(new Rum("ed", "Rd",1, 4, -1, -1));
karta.add(new Rum("Dd", "Df", -1, 0, 2, -1));
karta.add(new Rum("Fd", "Df", -1, -1, 6, 1));
karta.add(new Rum("Fd", "Dd", 2, -1, 5, 4));
karta.add(new Rum("Bd", "Dc", 0, -1, 3, -1));
karta.add(new Rum("Ld", "Dx", -1, -1, -1, 3));
karta.add(new Rum("Ud", "Ds", -1, -1, -1, 2));
return karta;
}
}
class Rum{
public String namn;
public String beskrivning;
public Integer n;
public Integer s;
public Integer o;
public Integer v;
public Rum(String namn, String beskrivning, Integer n, Integer s, Integer o, Integer v) {
this.namn = namn;
this.beskrivning = beskrivning;
this.n = n;
this.s = s;
this.o = o;
this.v = v;
}
public Integer getN() {
return n;
}
}
It sounds like you have a class that has a reference to the List and you want to get elements from the List using a 1-based index rather than the 0-based index that a List employs. A simple solution is to write a method that does the offset for you.
public Rum getRoom(int roomNumber) {
return karta.get(roomNumber - 1);
}
Consider using a Map keyed on a room ID instead of a List.

How Do I Create Dot Matrix Digits using Java Swing [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
How can I produce 5 x 7 dot matrix type digits for a clock project?
Here's an example of what I'm looking for.
I manually coded the position of each dot in each digit.
Is there a better way to create dot matrix digits?
By better I mean easier to code, easier to verify, makes use of existing fonts or other components, or anything else an experienced Swing developer might consider as an important consideration.
The rest of this question is the context for the naysayers that claim I didn't put enough effort into formulating my question.
Since I'm providing an answer to this question, I'm not posting fake bad code in the question. Sure, we appreciate it when people show their efforts. The code and text in my answer should supplement the question, in my opinion.
A few days ago, as I'm writing this, someone posted a question about making a clock with dot-matrix digits. The person posting the question provided code and a picture of what they had created. The person had created a BufferedImage where they had hardcoded the position of each square dot in his 4 x 7 dot matrix digits.
I was impressed with how much work the person had put into his BufferedImage, so I went off to my Eclipse to figure out how to generalize what he had done.
While I was away, people commented and closed his question. By the time I got back with my answer, the person had deleted his question.
Since I had what I thought was a good answer, I searched for an appropriate question. When I didn't find an appropriate question, I created a question.
Sure, I focused more on my answer than my question. Silly me, I thought that the answer would help provide context for the question.
Well, I hope that this explanation sheds some more light on why I thought this topic was important enough to create a question and ask for answers.
Unfortunately, you have to code the position of each dot in each digit.
However, you can do this in a flexible way.
Here's what I mean. A 5 x 7 dot matrix digit can be represented as a two-dimensional int array. It could also be represented as a boolean array, but a matrix of 0 and 1 values is easier to visually verify.
As an example. here's a method to code the zero digit. You can see that the ones create a visual outline that can be easily verified.
private int[][] defineZeroMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 1, 0, 0, 0, 1 };
matrix[3] = new int[] { 1, 0, 0, 0, 1 };
matrix[4] = new int[] { 1, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
It took me about 15 minutes to code all of the dot matrix digit matrices.
It's possible to code a dot matrix digit using a sparse matrix. Unfortunately, that idea leads to more code that's visually harder to verify.
Here's an example of the dot matrix digit two coded as a sparse matrix of coordinates.
private Point[] defineTwoCoordinates() {
Point[] array = new Point[14];
array[0] = new Point(0, 1);
array[1] = new Point(1, 0);
array[2] = new Point(2, 0);
array[3] = new Point(3, 0);
array[4] = new Point(4, 1);
array[5] = new Point(4, 2);
array[6] = new Point(3, 3);
array[7] = new Point(2, 4);
array[8] = new Point(1, 5);
array[9] = new Point(0, 6);
array[10] = new Point(1, 6);
array[11] = new Point(2, 6);
array[12] = new Point(3, 6);
array[13] = new Point(4, 6);
return array;
}
After we've coded all of the digit matrices, we'll create an array of matrices.
private int[][][] matrices;
The leftmost index is the digit, from 0 to 9. The second index is the row of the digit matrix. The third index is the column of the digit matrix.
Finally, we extend a JPanel and override the paintComponent method to actually paint the dot matrix digit.
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(dotColor);
for (int row = 0; row < matrices[digit].length; row++) {
for (int column = 0; column < matrices[digit][row].length; column++) {
if (matrices[digit][row][column] != 0) {
int x = margin + column * pixelWidth;
int y = margin + row * pixelWidth;
g.fillOval(x, y, dotWidth, dotWidth);
}
}
}
}
Here's a complete runnable example of how you would create a dot matrix digit panel by extending a JPanel, and use several dot matrix digit panels to create whatever GUI you want.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DotMatrixDigits implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new DotMatrixDigits());
}
#Override
public void run() {
JFrame frame = new JFrame("Dot Matrix Digits");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(defineTopPanel(), BorderLayout.BEFORE_FIRST_LINE);
frame.add(defineBottomPanel(), BorderLayout.AFTER_LAST_LINE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel defineTopPanel() {
JPanel panel = new JPanel();
panel.add(new DotMatrixDigit(0, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(1, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(2, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(3, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(4, Color.YELLOW, Color.BLACK));
return panel;
}
private JPanel defineBottomPanel() {
JPanel panel = new JPanel();
panel.add(new DotMatrixDigit(5, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(6, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(7, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(8, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(9, Color.YELLOW, Color.BLACK));
return panel;
}
/**
* <p>
* The <code>DotMatrixDigit</code> class creates a dot-matrix digit panel by
* extending <code>JPanel</code>. The dot matrix digit is 5 positions across and
* 7 positions down. The size of the dot and distance between dots are defined
* in the constructor of this class. The shape of the dot is determined in the
* <code>paintComponent</code> method.
* </p>
*
* #author Gilbert G. Le Blanc
* #version 1.8 - 20 October 2020
*
* #see JPanel
* #see Color
*/
public class DotMatrixDigit extends JPanel {
private static final long serialVersionUID = 1L;
/** int field to hold the digit to display **/
private int digit;
/** int field to hold the width of the dot in pixels **/
private int dotWidth;
/** int field to hold the distance between the
* top left corner of the dots in pixels **/
private int pixelWidth;
/** int field to hold the margin size in
* pixels surrounding the digit **/
private int margin;
private final Color dotColor;
private int[][][] matrices;
/**
* <p>
* This constructor creates a dot matrix digit panel. The preferred size of the
* panel is determined by the pixel width of each dot, including the space
* between the dots.
* </p>
*
* #param digit - The initial digit to display from 0 through 9.
* #param dotColor - The <code>Color</code> of the dots.
* #param backgroundColor - The background <code>Color</code> of the dot matrix
* digit panel.
*
*/
public DotMatrixDigit(int digit, Color dotColor, Color backgroundColor) {
this.digit = digit;
this.dotColor = dotColor;
this.dotWidth = 10;
this.pixelWidth = 15;
this.margin = dotWidth;
this.matrices = defineDigitMatricies();
int width = 4 * pixelWidth + dotWidth + margin + margin;
int height = 6 * pixelWidth + dotWidth + margin + margin;
this.setBackground(backgroundColor);
this.setPreferredSize(new Dimension(width, height));
}
private int[][][] defineDigitMatricies() {
int[][][] matrices = new int[10][][];
matrices[0] = defineZeroMatrix();
matrices[1] = defineOneMatrix();
matrices[2] = defineTwoMatrix();
matrices[3] = defineThreeMatrix();
matrices[4] = defineFourMatrix();
matrices[5] = defineFiveMatrix();
matrices[6] = defineSixMatrix();
matrices[7] = defineSevenMatrix();
matrices[8] = defineEightMatrix();
matrices[9] = defineNineMatrix();
return matrices;
}
private int[][] defineZeroMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 1, 0, 0, 0, 1 };
matrix[3] = new int[] { 1, 0, 0, 0, 1 };
matrix[4] = new int[] { 1, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
private int[][] defineOneMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 0, 1, 0, 0 };
matrix[1] = new int[] { 0, 1, 1, 0, 0 };
matrix[2] = new int[] { 1, 0, 1, 0, 0 };
matrix[3] = new int[] { 0, 0, 1, 0, 0 };
matrix[4] = new int[] { 0, 0, 1, 0, 0 };
matrix[5] = new int[] { 0, 0, 1, 0, 0 };
matrix[6] = new int[] { 1, 1, 1, 1, 1 };
return matrix;
}
private int[][] defineTwoMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 0, 0, 0, 0, 1 };
matrix[3] = new int[] { 0, 0, 0, 1, 0 };
matrix[4] = new int[] { 0, 0, 1, 0, 0 };
matrix[5] = new int[] { 0, 1, 0, 0, 0 };
matrix[6] = new int[] { 1, 1, 1, 1, 1 };
return matrix;
}
private int[][] defineThreeMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 0, 0, 0, 0, 1 };
matrix[3] = new int[] { 0, 0, 1, 1, 0 };
matrix[4] = new int[] { 0, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
private int[][] defineFourMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 0, 0, 1, 0 };
matrix[1] = new int[] { 0, 0, 1, 1, 0 };
matrix[2] = new int[] { 0, 1, 0, 1, 0 };
matrix[3] = new int[] { 1, 0, 0, 1, 0 };
matrix[4] = new int[] { 1, 1, 1, 1, 1 };
matrix[5] = new int[] { 0, 0, 0, 1, 0 };
matrix[6] = new int[] { 0, 0, 0, 1, 0 };
return matrix;
}
private int[][] defineFiveMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 1, 1, 1, 1, 1 };
matrix[1] = new int[] { 1, 0, 0, 0, 0 };
matrix[2] = new int[] { 1, 0, 0, 0, 0 };
matrix[3] = new int[] { 1, 1, 1, 1, 0 };
matrix[4] = new int[] { 0, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
private int[][] defineSixMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 1, 0, 0, 0, 0 };
matrix[3] = new int[] { 1, 1, 1, 1, 0 };
matrix[4] = new int[] { 1, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
private int[][] defineSevenMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 1, 1, 1, 1, 1 };
matrix[1] = new int[] { 0, 0, 0, 0, 1 };
matrix[2] = new int[] { 0, 0, 0, 0, 1 };
matrix[3] = new int[] { 0, 0, 0, 1, 0 };
matrix[4] = new int[] { 0, 0, 1, 0, 0 };
matrix[5] = new int[] { 0, 0, 1, 0, 0 };
matrix[6] = new int[] { 0, 0, 1, 0, 0 };
return matrix;
}
private int[][] defineEightMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 1, 0, 0, 0, 1 };
matrix[3] = new int[] { 0, 1, 1, 1, 0 };
matrix[4] = new int[] { 1, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
private int[][] defineNineMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 1, 0, 0, 0, 1 };
matrix[3] = new int[] { 0, 1, 1, 1, 1 };
matrix[4] = new int[] { 0, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
/**
* <p>
* The <code>setDigit</code> method sets the digit to display and repaints the
* panel.
* </p>
*
* #param digit - A digit from 0 through 9.
*/
public void setDigit(int digit) {
this.digit = digit;
this.repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(dotColor);
for (int row = 0; row < matrices[digit].length; row++) {
for (int column = 0; column < matrices[digit][row].length; column++) {
if (matrices[digit][row][column] != 0) {
int x = margin + column * pixelWidth;
int y = margin + row * pixelWidth;
g.fillOval(x, y, dotWidth, dotWidth);
}
}
}
}
}
}
Is there a better way to create dot matrix digits?
Don't know if 'better' (depends on whether effort or accuracy is the primary consideration) but there is a way to calculate the array based on the Shape of the digit.
Here is the result for a (bold) version of the default Monospaced font on this machine.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class FontToDotMatrix {
private JComponent ui = null;
Shape[] shapes = new Shape[10];
JComboBox fonts;
PixelArray[] pixelArrays = new PixelArray[10];
FontToDotMatrix() {
initUI();
}
public final void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
String[] fontFamilies = GraphicsEnvironment.
getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
fonts = new JComboBox(fontFamilies);
ui.add(fonts, BorderLayout.PAGE_START);
JPanel digitPanel = new JPanel(new GridLayout(2, 5, 4, 4));
ui.add(digitPanel);
digitPanel.setBackground(Color.RED);
for (int ii = 0; ii < 10; ii++) {
PixelArray pixelArray = new PixelArray();
pixelArrays[ii] = pixelArray;
digitPanel.add(pixelArray);
}
ActionListener listener = (ActionEvent e) -> {
for (int ii = 0; ii < 10; ii++) {
pixelArrays[ii].updatePixels(getLitPixels("" + ii));
}
};
fonts.addActionListener(listener);
fonts.setSelectedItem("Monospaced");
}
private Shape moveShapeToCenter(Shape shape) {
int w = 50;
int h = 70;
Rectangle2D b = shape.getBounds2D();
double xOff = -b.getX() + ((w - b.getWidth()) / 2d);
double yOff = -b.getY() + ((h - b.getHeight()) / 2d);
AffineTransform move = AffineTransform.getTranslateInstance(xOff, yOff);
return move.createTransformedShape(shape);
}
private boolean[][] getLitPixels(String digit) {
Font font = new Font(fonts.getSelectedItem().toString(), Font.BOLD, 70);
Shape shape = getShapeOfCharacter(font, digit);
Rectangle2D rect = shape.getBounds2D();
double h = rect.getHeight();
double ratio = 70d / h;
AffineTransform scale = AffineTransform.getScaleInstance(ratio, ratio);
shape = moveShapeToCenter(scale.createTransformedShape(shape));
boolean[][] bools = new boolean[5][7];
for (int yy = 0; yy < 7; yy++) {
for (int xx = 0; xx < 5; xx++) {
Point point = new Point((xx * 10) + 5, (yy * 10) + 5);
bools[xx][yy] = shape.contains(point);
}
}
return bools;
}
public JComponent getUI() {
return ui;
}
private Shape getShapeOfCharacter(Font font, String digit) {
BufferedImage bi = new BufferedImage(
1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
FontRenderContext frc = g.getFontRenderContext();
GlyphVector gv = font.createGlyphVector(frc, digit);
return gv.getOutline();
}
public static void main(String[] args) {
Runnable r = () -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
FontToDotMatrix o = new FontToDotMatrix();
JFrame f = new JFrame(o.getClass().getSimpleName());
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);
}
}
class PixelArray extends JPanel {
JLabel[][] labels = new JLabel[5][7];
PixelArray() {
setLayout(new GridLayout(7, 5));
BufferedImage bi = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
ImageIcon icon = new ImageIcon(bi);
for (int yy = 0; yy < labels[0].length; yy++) {
for (int xx = 0; xx < labels.length; xx++) {
JLabel l = new JLabel(icon);
labels[xx][yy] = l;
l.setOpaque(true);
add(l);
}
}
}
public void updatePixels(boolean[][] bools) {
for (int xx = 0; xx < labels.length; xx++) {
for (int yy = 0; yy < labels[0].length; yy++) {
JLabel l = labels[xx][yy];
if (bools[xx][yy]) {
l.setBackground(Color.WHITE);
} else {
l.setBackground(Color.BLACK);
}
}
}
}
}

java.lang.NullPointerException when referencing an array of ints from a different class

I'm making a project to go through a text file and output a tally of each letter in the file.
import java.util.*;
import java.io.*;
public class frequencyAnalysis {
private static String text;
public static String alphabet;
public static int Freq[];
public frequencyAnalysis(String text) {
this.text = text;
int [] Freq = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //array of ints to keep track of how many of each letter there is.
alphabet = "abcdefghijklmnopqrstuvwxyz"; //point of reference for the program to know which number in the array should be increased
}
public static void freqAnalysis() throws IOException {
String token = "";
int index;
File subset = new File(text); //creates a new file from the text parameter
Scanner inFile = new Scanner(subset);
while(inFile.hasNext()) {
token = inFile.next();
index = alphabet.indexOf(token);
if (index == -1) { //makes sure that the character is a letter
break;
} else {
Freq[index]++;
}
}
inFile.close();
}
}
This is the class that's supposed to go through a given text file, and count how many of each letter there is in it.
import java.util.*;
import java.io.*;
public class tester {
public static void main(String args[]) throws IOException {
Scanner in = new Scanner(System.in);
System.out.println("Please type the input file path: "); //allows the user to specify a file
String input = in.next();
frequencyAnalysis Freq = new frequencyAnalysis(input);
frequencyAnalysis.freqAnalysis(); //calls the method to run through the file
for(int i = 0; i <= 25; i++){ //prints the alphabet and the Freq array
System.out.println(frequencyAnalysis.alphabet.charAt(i) + ": " + frequencyAnalysis.Freq[i]); //this is where the error is
}
}
}
This is the implementation class, which allows the user to specify a file and then runs the freqAnalysis method to adjust the static Freq array, which is then printed. However, when I run the program it gives me a java.lang.NullPointerException error on the specified line. I've already figured out that the problem is in "frequencyAnalysis.Freq[i]", not in "frequencyAnalysis.alphabet.charAt(i)". However, I don't know what the problem is or how to fix it.
In the constuctor you create an initialize local variable int [] Freq instead of class field.
Instead of:
int [] freq = {0, 0, 0, 0, 0, 0, ...
you should have:
freq = {0, 0, 0, 0, 0, 0, ...
Ok so you aren't initializing the array correctly in your frequencyAnalysis class.
public static int Freq[];
you think you're initializing it with
int [] Freq = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
but in reality it should be:
this.Freq = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
The other answers are decent, but have some flaws in coding style.
First of all, integer arrays default to initialize with zeroes, so you can simplify your initialization of Freq. Also, you created a local variable Freq inside of your constructor for frequencyAnalysis instead of setting the static class variable.
You should change your constructor to this:
public frequencyAnalysis(String text) {
this.text = text;
frequencyAnalysis.Freq = new int[26]; //array of ints to keep track of how many of each letter there is.
alphabet = "abcdefghijklmnopqrstuvwxyz"; //point of reference for the program to know which number in the array should be increased
}
Also, class names should always be capitalized! (Change it to FrequencyAnalysis)
To let you know that is happening,
public frequencyAnalysis(String text) {
this.text = text;
int [] Freq = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //array of ints to keep track of how many of each letter there is.
alphabet = "abcdefghijklmnopqrstuvwxyz"; //point of reference for the program to know which number in the array should be increased
}
When you do this int [] Freq is a new local variable the scope is limited to constructor and at the other side public static int Freq[]; is still Null, point to same variable for initialization, as stated above by others

representing a matrix with column/row labels

I would like to create a 2d Array with Java, or a Matrix with a int numbers.
I've already did that..but I still don't know how to assign labels to the rows/columns.
I would like to be able to access any number inside the matrix based on the row/columns
This is my java code
Gson gson = new Gson();
int[][] data = {{78, 0, 0, 0, 0}, {0, 54, 0, 0, 0}, {0, 0, 12, 0, 0}, {0, 0, 0, 74, 0}, {0, 0, 0, 0, 11}};
String json = gson.toJson(data);
// Convert JSON string into multidimensional array of int.
int[][] dataHeatMap = gson.fromJson(json, int[][].class);
for (int[] i : dataHeatMap) {
for (int j : i) {
System.out.print(j + " ");
}
System.out.println("");
}
return json;
You can use Enums:
public enum ROW {a, b, c, d, e}
public enum COL {f, g, h, i, j}
data[ROW.a.ordinal()][COL.f.ordinal()] = 3;
Use ENUM types which does represend the special index of your 2dim Array. Give them a field called value/name/... and create them with the index of them in the array. Afterwards you can easy call them with getting their letter-value which does represent the array index.
It´s very readable and ENUM.<VALUE> does not represent an INT value. So this is the way how you can do it.
public enum ROW {
A(0), B(1), C(2), D(3), E(4);
private final int value;
ROW(int value) { this.value = value; }
public int getValue() { return value; }
}
public enum COL {
F(0), G(1), H(2), I(3), J(4);
private final int value;
COL(int value) { this.value = value; }
public int getValue() { return value; }
}
public static void main(String []args){
int[][] matrix = {{78, 0, 0, 0, 0}, {0, 54, 0, 0, 0}, {0, 0, 12, 0, 0}, {0, 0, 0, 74, 0}, {0, 0, 0, 0, 11}};
System.out.println("Value: " + matrix[ROW.A.getValue()][COL.F.getValue()]);
}
I would prefer the way above because you see what directly happens and can assign any value you want. But you just can use ENUM.ordinal(), too.
Then data[ROW.a.ordinal()][...] will return 0 for ROW because it´s listed first. b will return 1,... It just depends on the way they are listed/created on the ENUM.

MultipleSelectionModel: which list change events to expect from selectedIndices?

... in particular when modifying the underlying items?
Below is a quick example that selects a range and adds an item above the selection for TableView and ListView. The selectedIndices before/after adding:
indices before modification: [2, 3]
indices after modification: [3, 4]
Expected options:
a single wasReplaced for the whole range
a wasRemoved for the "2" and a wasAdded for the "4"
??
Actual:
table's selection fires two events, each with a single wasAdded
list's selection fires a wasPermutated (that's nuts, or what am I missing?)
Output (jdk8u40b12):
Change #0 on TableView indices
list = [3]
Change event data:
class javafx.scene.control.MultipleSelectionModelBase$3
javafx.scene.control.MultipleSelectionModelBase$3#4ececa
cursor = 0
Kind of change: added
Affected range: [0, 1]
Added size: 1
Added sublist: [3]
Change #1 on TableView indices
list = [3, 4]
Change event data:
class javafx.scene.control.MultipleSelectionModelBase$3
javafx.scene.control.MultipleSelectionModelBase$3#b0161d
cursor = 0
Kind of change: added
Affected range: [1, 2]
Added size: 1
Added sublist: [4]
Change #0 on ListView indices
list = [3, 4]
Change event data:
class com.sun.javafx.collections.NonIterableChange$SimplePermutationChange
{ permutated by [4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0] }
cursor = 0
Kind of change: permutated
Affected range: [0, 2]
Permutation: [0->4, 1->3]
The producing code:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.ListChangeListener.Change;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
public class SelectedIndicesOnItemsModified extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
ObservableList<Integer> items = FXCollections.observableArrayList(1, 2, 3, 4);
TableView<Integer> table = new TableView<>(items);
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
table.getSelectionModel().selectRange(2, 4);
System.out.println("indices before modification: " +
table.getSelectionModel().getSelectedIndices());
ListView<Integer> list = new ListView<>(items);
list.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
list.getSelectionModel().selectRange(2, 4);
new PrintingListChangeListener("TableView indices ",
table.getSelectionModel().getSelectedIndices());
new PrintingListChangeListener("ListView indices ",
list.getSelectionModel().getSelectedIndices());
items.add(0, 111);
}
public static void main(String[] args) {
launch(args);
}
public static <T> void prettyPrint(Change<? extends T> change) {
StringBuilder sb = new StringBuilder("\tChange event data:\n");
sb.append("\n " + change.getClass() + "\n " + change);
int i = 0;
change.reset();
while (change.next()) {
sb.append("\n\tcursor = ").append(i++).append("\n");
final String kind = change.wasPermutated() ? "permutated" : change
.wasReplaced() ? "replaced"
: change.wasRemoved() ? "removed"
: change.wasAdded() ? "added"
: change.wasUpdated() ? "updated" : "none";
sb.append("\t\tKind of change: ").append(kind).append("\n");
sb.append("\t\tAffected range: [").append(change.getFrom())
.append(", ").append(change.getTo()).append("]\n");
if (kind.equals("added") || kind.equals("replaced")) {
sb.append("\t\tAdded size: ").append(change.getAddedSize())
.append("\n");
sb.append("\t\tAdded sublist: ")
.append(change.getAddedSubList()).append("\n");
}
if (kind.equals("removed") || kind.equals("replaced")) {
sb.append("\t\tRemoved size: ").append(change.getRemovedSize())
.append("\n");
sb.append("\t\tRemoved: ").append(change.getRemoved())
.append("\n");
}
if (kind.equals("permutated")) {
StringBuilder permutationStringBuilder = new StringBuilder("[");
for (int k = change.getFrom(); k < change.getTo(); k++) {
permutationStringBuilder.append(k).append("->")
.append(change.getPermutation(k));
if (k < change.getTo() - 1) {
permutationStringBuilder.append(", ");
}
}
permutationStringBuilder.append("]");
String permutation = permutationStringBuilder.toString();
sb.append("\t\tPermutation: ").append(permutation).append("\n");
}
}
System.out.println(sb.toString());
};
public static class PrintingListChangeListener implements ListChangeListener {
String source;
int counter;
public PrintingListChangeListener() {
}
public PrintingListChangeListener(String message, ObservableList<?> list) {
list.addListener(this);
source = message;
}
#Override
public void onChanged(Change change) {
System.out.println("Change #" + counter++ + " on " +source +
"\nlist = " + change.getList());
prettyPrint(change);
}
}
}
Filed two issues, RT-39393 for ListView, RT-39394 for TableView
A tentative partly answer to my own question
Notification count
Number of notification (aka: calls to changed(Change c)) should be the same as number in underlying data, in pseudo-code
itemsChanges = 0;
itemsListener = c -> itemsChanges++;
getItems().addListener(itemsListener);
selectedChanges = 0;
selectedListener = c -> selectedChanges++;
getSelectedIndices().addListener(selectedListener);
getItems().modifySomehow(...);
assertEquals(itemsChanges, selectedChanges);
Change Types
Thinking about it, most changes in the underlying items seem to map to a replaced in the selectedIndices ("value" below denotes the elements in the selectedIndices):
"real" wasAdded: all values greater than the insertion location must be increased by addedSize
// selectedIndices before
[2, 4]
items.add(0, something);
// selectedIndices after
[3, 5]
-> net effect: two values are set (== replaced by) to a new value
"real" wasRemoved: all values pointing to removed items must be removed as well, values greater than the remove location must be decreased by removedSize
// selectedIndices before
[2, 4, 5, 8]
items.removeAll(items.get(3), items.get(5))
// selectedIndices after
[2, 3, 6]
-> net effect: replace [4, 5, 8] at pos 1 by [3, 6]
wasUpdated: indices are unchanged, though the underlying items did change somehow. Depending on context, it might be a good idea to pass those updates through to its listener or not.
Still open: replaced/permutation in items
To get those expected (at least by my paper coding :-) notifications correct, isn't quite trivial - and went wrong in MultipleSelectionModelBase and subclasses. Currently playing with moving all the nasty details into a dedicated IndicesList (which is-a TransformList with items as sourceList)

Categories

Resources