Continuously read from file and do an action - java

I want to continuously read from a text file, and change the color of a box I have shown on the canvas when a certain line is read (the text file is going to be constantly updating). Right now, I have a green square drawn on the canvas and three "test" lines in the text file, and when it reaches the third line of the text file I would like to change the the square to Red.
Here is my code, from two files (myCanvas.java and myFileReader.java). Any point in the right direction is greatly appreciated.
public class myCanvas extends Canvas{
public myCanvas(){
}
public void paint(Graphics graphics){
graphics.setColor(Color.green);
graphics.fillRect(10, 10, 100, 100);
graphics.drawRect(10,10,100,100);
}
public static void main(String[] args){
myCanvas canvas = new myCanvas();
JFrame frame = new JFrame("Live GUI");
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(canvas);
frame.setVisible(true);
myFileReader read = new myFileReader();
read.readFromFile();
if(myFileReader.strLine == "This is the third line."){
//change color
}
}
public class myFileReader{
public static String strLine;
public void readFromFile()
{
try{
FileInputStream fstream = new FileInputStream(System.getProperty("user.dir")+"\\sample.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
while (true){
strLine = br.readLine();
if(strLine == null) {
Thread.sleep(1000);
}
}
}
catch (Exception ex){
System.err.println("Error: " + ex.getMessage());
}
}
}

Here is a way you can do it without much changes to your code.
Create a local variable in your MyCanvas class called currentColor of type Color. FYI, the convention in Java is to have class names start with a capital letter.
Update your paint() method to set the color of the rectangle to the new variable currentColor, instead of the static green value.
In your main method, you can do canvas.currentColor = <new color here>; and then canvas.repaint(). The repaint() function call will erase the canvas and redraw it using your paint() function.
I don't think your FileReader will work well with a file that's constantly being modified though.

Simply add a counter and increment it each time you read a line. When the counter reaches the third line use an if statement to do your task

Try this
1.Use BreakIterator class, with its static method getLineInstance(),
this will help you identify every line in the file.
2. Create an HashMap with the colour as Key, and its RGB as Value.
3. Parse every word in the line, which is obtained from
BreakIterator.getLineInstance().
4. Compare it with the Key in the HashMap,
if the word in the line happens to match the Key in
the HashMap, then colour the box with the Value of the Key.

Related

Disable the mouse cursor within a program

I'm creating a text adventure and I need to completely disable the mouse cursor. Not just hide it, although I already know how to do that, but disable it completely so that you must use Alt-Tab or a built-in quit button to stop. The main reason for this is because people can scroll with the mouse cursor and I need to disable that, I thought about canceling MouseEvents when they're fired but I couldn't get it to work (the listener that is.)
If someone knows how then please speak up and tell me! :)
EDIT: Whoops, I forgot my code. Here is my Console class.
This is started by another class with new Console();
EDIT 2: Here are some snippets of me trying to create an invisible cursor and a mouse listener. The first one works, but the latter does not.
// Invisible cursor
Toolkit toolkit = Toolkit.getDefaultToolkit();
Point hotSpot = new Point(0,0);
BufferedImage cursorImage = new BufferedImage(1, 1, BufferedImage.TRANSLUCENT);
Cursor invisibleCursor = toolkit.createCustomCursor(cursorImage, hotSpot, "InvisibleCursor");
frame.setCursor(invisibleCursor);
// Adding mouse listener
frame.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
System.out.println(me);
}
});
EDIT 3: To elaborate on the mouse listener it simply does not work. It doesn't print anything.
If you just want to prevent users from seeing old text, remove the old text from the JTextArea.
The easiest way to do it is to leave the JTextArea in a JScrollPane, and keep track of the lines yourself:
private static final int MAX_VISIBLE_LINES = 12;
private final Deque<String> lines = new LinkedList<>();
void appendLine(String line,
JTextArea textArea) {
lines.addLast(line);
if (lines.size() > MAX_VISIBLE_LINES) {
lines.removeFirst();
}
String text = String.join("\n", lines);
textArea.setText(text);
textArea.setCaretPosition(text.length());
try {
textArea.scrollRectToVisible(
textArea.modelToView(text.length()));
} catch (BadLocationException e) {
throw new RuntimeException(e);
}
}
Trying to commandeer the mouse on a multitasking desktop is just going to make users angry. Would you want an application preventing you from reading your e-mail?
Update:
If you want to base the number of lines of text on the JTextArea’s current height, use the JTextArea’s font metrics. I assume you don’t need to get it exactly right and it’s okay if the number is off by one or two lines. (To account for things like line wrapping would be considerably more difficult.)
private final Deque<String> lines = new LinkedList<>();
void appendLine(String line,
JTextArea textArea) {
FontMetrics metrics = textArea.getFontMetrics(textArea.getFont());
JViewport viewport = (JViewport) textArea.getParent();
int visibleLineCount = viewport.getExtentSize().height / metrics.getHeight();
lines.addLast(line);
while (lines.size() > visibleLineCount) {
lines.removeFirst();
}
String text = String.join("\n", lines);
textArea.setText(text);
textArea.setCaretPosition(text.length());
try {
textArea.scrollRectToVisible(
textArea.modelToView(text.length()));
} catch (BadLocationException e) {
throw new RuntimeException(e);
}
}

Java Listener for looped combo in Eclipse SWT

I have a Java SWT GUI that I've built using Eclipse. I'm using a while loop to reference a text file. The while loop iterates through each line of the text file and builds a series of combo or text boxes for specific items on each line. Each line represents one visual column in the GUI and, depending on how many items I have in the text file, the GUI builds to the right. For simplicity's sake I am including just the code that I am trying to figure out.
For instance, assume I have three lines that create six combo boxes in the GUI (three columns by two rows). I would like a change on the top row in the second column to execute a Listener on the bottom row, also in the second column. However, right now the Listener loops through all of the combo's and makes a change to all three, not just the one I want. I can't figure out how to make this work. See the code below. I appreciate the help.
private void buildMultipleSatPulldowns() {
try {
FileReader fr = new FileReader("MultipleSatellites.txt");
BufferedReader br = new BufferedReader(fr);
String line = null;
String[] tempS;
String constellation = null;
String satellite = null;
while ((line = br.readLine()) != null) {
tempS = line.split("~");
constellation = tempS[4];
satellite = tempS[6];
constNameCombo = new Combo(satellitesComposite2, SWT.NONE);
constNameCombo.setToolTipText("Pulldown constellation name");
constNameCombo.setBounds(startX + x2, 71, 125, 28);
constNameCombo.setItems(constNameArray);
constNameCombo.setText(constellation);
constNameCombos.add(constNameCombo);
constNameCombo.addModifyListener(new ModifyListener() { // captures changed combo values
public void modifyText(ModifyEvent arg0) {
setConstellationPD();
}
});
sPullDown(constellation); // builds the satellite array for the constellation and populates each pulldown
satNameCombo = new Combo(satellitesComposite2, SWT.NONE);
satNameCombo.setToolTipText("Pulldown satellite name");
satNameCombo.setBounds(startX + x2, 106, 125, 28);
satNameCombo.setItems(satNameArray);
satNameCombo.setText(satellite);
satNameCombos.add(satNameCombo);
startX = startX + nextX;
}
br.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void setConstellationPD() {
int constellations = 0;
for (Combo constNameCombo : constNameCombos) {
// What do I do here so that only the desired satNameCombo changes to reflect the desired pull down?
setSatellitesPD(constellations, constNameCombo)
constellations++;
}
}
private void setSatellitesPD(int c, String cN) {
int satellites = 0;
for (Combo satNameCombo : satNameCombos) {
if (c == satellites) {
satNameCombo.setText(satNameCombos.get(satellites).toString());
satNameCombo.removeAll();
sPullDown(cN);
satNameCombo.setText("select Satellite");
}
satellites++;
}
}
private void sPullDown(String cName) {
// sPullDown takes the constellation name and returns a String Array of all objects in the constellation. This code works correctly when called.
}
If I understood correctly, you need a way to know which combo fired the event in order to affect some other components.
SWT events like ModifyEvent have the method getSource() which will return the object on which the event occurred.
Having that you just need to properly identify it; for example you could simply use constNameCombos.indexOf(eventCombo) to retrieve its index.
Or, more efficiently, you could attach some data to your combos with the method setData and retrieve it inside the event with getData, for example inside the loop:
// "i" would be the index of the combo
constNameCombo.setData("index", i);
i++;
and in the event:
Combo eventCombo = (Combo) arg0.getSource();
int index = eventCombo.getData("index");
With these information you should be able to identify the other components that you want to change.

Can't Run Method and Its GUI From Inside a Try Catch

I am trying to execute the lines:
Balldemo bd = new BallDemo();
bd.bounce(myInt);
In the below code:
public void actionPerformed(ActionEvent evt) {
String text = textField.getText();
try {
myInt=Integer.parseInt(textField.getText());
BallDemo bd = new BallDemo();
bd.bounce(myInt);
int newInt = myInt + 5;
System.out.println("Integer is: "+newInt);
}
catch (NumberFormatException ex) {
System.out.println("Not a number");
}
//Make sure the new text is visible, even if there
//was a selection in the text area.
textArea.setCaretPosition(textArea.getDocument().getLength());
}
But is does not boot the program correctly as follows:
program is a canvas with two balls that move, bounce(int numberOfBalls) will draw the balls on the canvas and start them moving.
In the above code, the canvas is created but the balls do not appear.
However, in a different class under the main method it works fine.
Basically don't understand why it won't successfully execute in a try-catch loop.
I suspect your BallDemo object (bd) is going out of scope as soon as the try block ends. Try declaring it outside the try block.

Input file which contains 2D coordinates for a rectangle

I am struggling to read in 2D coordinates from an input file which should then create rectangles in a rectangle class. I am wondering how I would go about starting this as I am new to programming, such as how to layout the coordinates in the file and how to read them in using like a X1 Y1 X2 Y2 format to create a rectangle in the rectangle class. Thanks.
Read BufferedReader from https://www.mkyong.com/java/how-to-read-file-from-java-bufferedreader-example/ . It is an example of bufferedReader which is reading per line. Using this, you can put your text files values to your program.
This is a program I created for you
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFileExample2 {
//variable for file name with specified file path
private static final String FILENAME = "\*your directory*\filename.txt";
//List variable -> higher level of array because List is a flexible array
private static List<double> coordinates = new ArrayList<double>();
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader(FILENAME))) {
//this will add values from your textfile per line to List
while ((coordinates.add(br.readLine())) != null) { }
} catch (IOException e) {
e.printStackTrace();
}
}
}
This will solve one of your issue but this is just for you to move on not to solve all issues.
Your textfile should contain values like this
12
32
23
12
4 points for coordinates but per line. Your List coordinates will have it by running while ((coordinates.add(br.readLine())) != null) { }
research how to use list . It's a great thing to know.
Now study how to implement GUI using either JFrame or Applet.
Issues:
GUI : using JFrame
Read Text File : using BufferedReader
Array : using List, a higher level of array

Determining what text exists in an area of a JTextArea when the text is right to left

I have some code which tries to determine what text is within a given vertical slice of a text area where the vertical slice is specified as Y coordinates instead of lines.
Converting to using line maths is a fine workaround for this issue, by the way, so that is what I'm going to go with, but I can envisage cases where you might only have a Y coordinate and it seems like this sort of thing would come up so I'm going to ask it anyway.
I reduced my issue down to a fairly minimalist (lol Java) example. We display a frame with some text and then attempt to determine the character offset of the text closest to the start of the text area. We know from commonsense that it will be 0, but figuring that out programmatically is the problem.
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new RtlTest().run();
}
});
}
JFrame frame;
JTextArea textArea;
public void run() {
textArea = new JTextArea(
"\u05D4\u05D5\u05D3\u05E2\u05EA \u05D8\u05D9\u05D9\u05D2\u05E8 " +
"\u05D8\u05E7\u05E1\u05D8 \u05D1\u05E2\u05D1\u05E8\u05D9\u05EA");
frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(textArea), BorderLayout.CENTER);
frame.setSize(400, 300);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
measure();
}
});
}
public void measure() {
try {
System.out.println("Either the line is left to right or it's right to left " +
"(or a mix), so one of these two values should be 0:");
System.out.println(textArea.viewToModel(new Point(0, 0)));
System.out.println(textArea.viewToModel(new Point(textArea.getWidth() - 1, 0)));
Rectangle firstLetterView = textArea.modelToView(0);
System.out.println("This one should definitely be 0, right? " +
"I mean, we got the coordinates from Swing itself:");
System.out.println(textArea.viewToModel(new Point(firstLetterView.x,
firstLetterView.y)));
frame.dispose();
} catch (BadLocationException e) {
throw new IllegalStateException(e);
}
}
The output is rather surprising:
Either the line is left to right or it's right to left (or a mix),
so one of these two values should be 0:
23
23
This one should definitely be 0, right? I mean, we got the coordinates from Swing itself:
24
Points of surprise:
The character closest to the top left corner is not character 0.
The character closest to the top right corner is not character 0.
The character closest to the position of character 0 is not character 0.
Add the following line in your code:
textArea.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
Your output numbers will change - but your text will show from the right side of the text area. I hope this is what you want.
EDIT:
According to this Hebrew and Arabic should be in RT orientation.

Categories