Okay, thus may seen kind of odd, but I wanted to get some suggestions from everyone here. I am a beginning Java developer (after 2 years of ASP.NET web development) and I have recently began working on my first Java project - a calculator. I realize that their are tons of calculators out there, but I thought it would be a good beginner project.
Anyway, here is what I need help with. Currently, I am using a Scrolling JTextArea for display (instead of a simple JTextField) that is approximately 5 rows tall. I want the user to be able to scroll through the list to see previous entries and such. The format of the box will be equation on one line and the program will generate the answer on the next and so on.
My real question is, how is the best way to implement this? My fist idea was to read through the JTextArea when equals is pressed, down to the last line and try to search that line for the operator (+, -, etc.) and the operands. Is this the best way to go about this? Although, this would work would work, I think it could get cumbersome and sounds very inefficient. I am open to any suggestions, even possibly replacing the JTextArea is some other component would work better.
Thanks!
There's no need to read through the JTextArea contents - use JTextArea.append() to add to the end. Here are some examples of JTextArea content manipulation:
JTextArea ta = new JTextArea("Initial Text");
// Insert some text at the beginning
int pos = 0;
ta.insert("some text", pos);
// Insert some text after the 5th character
pos = 5;
ta.insert("some text", pos);
// Append some text
ta.append("some text");
// Replace the first 3 characters with some text
int start = 0;
int end = 3;
ta.replaceRange("new text", start, end);
// Delete the first 5 characters
start = 0;
end = 5;
ta.replaceRange(null, start, end);
If you are open to different interfaces, you might want to try something like a JTextField at the top of your view, from which you can receive as input your 'new' inputted equation, and then below it with the same width a JList that would scroll to have all of the previous equations and their results. That would make parsing of the current formula much easier, and you would also have an easy time of keeping your previous formula and their results in a scrollable list, with the easy option of keeping the most recent on top.
your idea is interesting. so you would have a line such as.
2+2
then when pressing calculate would add the line
4
and so on then you could type in another equation.
it could work but as you said it wouldn't be the most efficient implementation... but that's just a tradeoff of getting the desired functionality.
If i were going to implement it the way you discribed (with a JTextArea) I'd use scanner, and scan the value string a line at a time.
if the line has +/- in it then do the calculation and add both the original line and the answer to a string.
the new string is the new value of the text field.
this method would get pretty cumbersom as you would be continually recalculating the users old entries more were added.
I guess if you continually stored the last line of the document, when you run out of lines, calculate the last stored and append the answer, then it wouldn't be so bad.
Here's what I would do:
use a JTextField to enter in the calculations, and a JList to display the old ones and their answers.
You could treat each line as a single operation. That way you could use the String array returned directly by:
String [] operations = textArea.getText().split("\n");
And then you'll know that exactly each one of them as a complete operation ( may be invalid, but that' another story )
Is this what you asked or do I totally misread you?
I think a simpler solution would actually use two components. A TextArea to hold the "history" of what's happened so far, and a textfield where the user inputs new entries.
Thanks to everyone who replied. You all gave me some ideas to think about. I think right now, I am going to go with my original idea of using a single JTextArea and try to find ways to optimize the process. If that gets too difficult (which is very possible), I will follow the majority's advice and use two separate fields. Thanks for replying everyone!
Related
I'm sorry if the title is vague. It's because I don't know exactly what it is called.
I am creating a program for a school project and I'm trying to figure out a shorter version of a code that I already got.
The interface looks like this:
Interface
The other parts of the program are not really necessary to put on here. They just input texts/strings in the first row textfields and shifts down one column every time new info is put in the first row.
The buttons on the right (the ones with the [x]) are the ones that are coded. They remove the text/string in the row next to them and shifts up the texts from below (if there are any) by one column.
The code for the first button is such:
CC01.setText(CC02.getText());
SC01.setText(SC02.getText());
SU01.setText(SU02.getText());
SD01.setText(SD02.getText());
SR01.setText(SR02.getText());
CC02.setText(CC03.getText());
SC02.setText(SC03.getText());
SU02.setText(SU03.getText());
SD02.setText(SD03.getText());
SR02.setText(SR03.getText());
CC03.setText(CC04.getText());
SC03.setText(SC04.getText());
SU03.setText(SU04.getText());
SD03.setText(SD04.getText());
SR03.setText(SR04.getText());
CC04.setText(CC05.getText());
SC04.setText(SC05.getText());
SU04.setText(SU05.getText());
SD04.setText(SD05.getText());
SR04.setText(SR05.getText());
CC05.setText(CC06.getText());
SC05.setText(SC06.getText());
SU05.setText(SU06.getText());
SD05.setText(SD06.getText());
SR05.setText(SR06.getText());
CC06.setText(CC07.getText());
SC06.setText(SC07.getText());
SU06.setText(SU07.getText());
SD06.setText(SD07.getText());
SR06.setText(SR07.getText());
CC07.setText(CC08.getText());
SC07.setText(SC08.getText());
SU07.setText(SU08.getText());
SD07.setText(SD08.getText());
SR07.setText(SR08.getText());
CC08.setText(CC09.getText());
SC08.setText(SC09.getText());
SU08.setText(SU09.getText());
SD08.setText(SD09.getText());
SR08.setText(SR09.getText());
CC09.setText(CC10.getText());
SC09.setText(SC10.getText());
SU09.setText(SU10.getText());
SD09.setText(SD10.getText());
SR09.setText(SR10.getText());
CC10.setText("");
SC10.setText("");
SU10.setText("");
SD10.setText("");
SR10.setText("");
So, yes, I have ten of these buttons. And the code for each button reduces by one 5-line code. For example, Button1's code is the one you see up top, then Button2's code starts from the [CC02...], the Button3 starts from [CC03], etc.
I think I used the brute force method of this code which I don't think is efficient and makes my code too long (the code for the ten [x] buttons alone is around 400 lines).
I asking of there is a much shorter way of doing this method.
Thanks.
I've been working on a GUI to handle DNA sequences. Most of the molecules will be plasmids, which are circular forms of DNA. I can get a sequence as a string and display it in a JTextPane, but I'm not sure how to handle cases where the user might want to select a section of the sequence that crosses from the end to the beginning of the sequence. One thing I've considered is displaying the sequence twice, so you can select the last part of the first section and the first part of the last section, then overwriting some function so that copying the text will put the correct sequence on the clipboard instead of the string that was actually selected. (I'll have to do that anyway, I'm displaying the forward and reverse strands of the DNA, then a blank line, so that 1 "line" of actual sequence becomes 3 lines of text.
Is there some trick to circular strings that I just don't know about?
Do you know how other programs handle the selection of pieces of circular DNA? You might be able to get some inspiration from other software, like alignment viewers (supporting circular DNA) in this list on Wikipedia: en.wikipedia.org/wiki/List_of_alignment_visualization_software.
I think it would be wise to decide on how you want the GUI to work first, and then start working on your code. Otherwise you risk wasting a lot of time on implementing ideas that you end up not using.
You could even consider offering both a circular and a linear view on the same sequencing data, as this screenshot from the CLC Sequence Viewer shows:
Is there a way to adjust the spacing between new lines when outputting to the console through System.out.println? I'm attempting to print out a square with a basic nested for-loop, but I keep getting a rectangle despite having the right number of characters. This is because the spacing between the characters is different than the spacing between lines. Any ideas?
The standard output stream is just a stream of data; how that data is displayed is up to the application displaying it (e.g. a terminal or your IDE). You'll either have to settle for a rectangle, or find a different method of output than standard out.
Without your current code, it's hard to say exactly whats going on. My first thought is, make sure you're using a character that is as high as it is wide, e.g. *.
Second thought is (and again, I have no code to reference), see if you get the same result using one of the algorithms here: Printing a Square with loops, perhaps there is an issue with the square-printing logic that you overlooked.
In order to be able to display a sentence on a, say, JPanel with a GridLayout(1,0) [i.e., only one line/row] and then be able to draw a syntax tree (or similar) above it, I want to display the sentence as a row of Strings, which each include one word.
The single Strings should then be either selectable (as in a JList), or I should at least be able to get their Location on the JPanel via getLocation().
Up to this point I have tried the following options, and had the following issues:
- Single Strings as JLabels: The JLabels are stretched out to fill the JPanel width, re-sizing them to fit the single String they're displaying seems complicated. I would want to be able to do this, however, to make the sentence look like a sentence and not like a badly layed out table.
- JList: All the functionality I want, but I'm unaware of an option to re-size the "cells" of a single String (cf. JLabel above). Also, I'm having difficulties restricting display of the JList to a single line/row (cf. another of my questions).
- JTextArea: I couldn't get my head round how to get the Location of the single Strings that I had appended to the JTextArea.
I'm aware that drawString() might be an option, but I'm afraid to use it since I don't want to mix AWT and Swing. Also, I would need to calculate the int values for x and y for every single String. And I'm not sure whether I'd be able to get their Locations at all (although I could of course save their ints in a Map or Vector since I have to calculate them anyway).
Thankful for any suggestions! Thanks!
I would use JTextArea and method modelToView()/viewToModel() to get x,y for position in nthe string and position in the string for coordinates x and y.
Also use Utilities class getWordStart() getWordEnd() getRowStart() getRowEnd() methods.
EDIT: As noted by camickr in the comments, setSize() is not an appropriate way to lay out Components (as this is automatically done by the respective LayoutManager, I have removed the respective code from my answer.
Triggered by StanislavL's answer, I have found a solution to do it via JTextField, albeit by using one for each String rather than just one (as suggested by StanislavL).
I can now easily getLocation() for each JTextField. Simple, really!
I'd like to thank StanislavL for his answer, without which I'd never have though about this, and camickr for his comment.
I have a JLabel that needs to display some html-formatted text. However, I want to restrict this to being 4 lines long (and if so, provide a button to see everything).
So far, I've tried setting the maximum size manually or via a layout manager. However, both of these solutions can cause part of a line to be displayed.
edit: To add a little more details, I need to force 4 lines even when respecting line wrapping correctly, resizing components, and changing font sizes. I've considered handling resize/fontsize changes by replacing the label with a new one that fits correctly.
JLabel seems to handle incomplete tags well, so I could probably do something like a binary search on the input string finding which character would cause it to go over the 4 line limit (using FontMetric to determine how many pixels 4 lines would be), and then replacing an existing label with the new one. The big downside to this approach is that I need to run the computation every time the user resizes the panel or changes fonts (and it feels like a dirty dirty hack).
Add the JLabel to a JScrollPane as set the scrollpane with a reasonable preferred size. Scrollbars will appear a necessary.
I don't know of any absolute solution to the questions since I doubt you can define what a "line" is. One line of text may be font 12 and another 24. I don't know of any way to calculate the height of each given line.
Even if you did use a ComponentListener to handle the componentResized() event I'm not sure you can come up with a reasonable algorithm to to calculate the exact width/height of of a 4 line display.
I would try running through the String of text and removing all text after the third "\n"
String shortenText(String oldtext){
String newText = "";
for(int i=0;i<3;i++){
newText += oldtext.substring(0,oldtext.indexOf("\n"));//adds one line to String
oldtext = oldtext.substring(indexOf("\n")+1);//shorten old string to prepare for next iteration
}
return newText;
}
You may also want to try the same algorithm, except strip of <p> and <br> tags as well...
If you know the values of the possible tags just switch the text from "\n" to "<br>" or any tag you need
Hey, I found a way that works. The framework I'm working with allows me to create a listener for font size changes. In this listener, I determine what the new max size of the label is (getFontMetrics(font).getHeight() * 4) and then re-set the maximum height on the label to this and then relayout everything. This even handles the word wrap case well. I'm guessing that someone could do nasty things with silly HTML input, but this covers the 99% case pretty well.