How to format a table in JOptionpane? - java

So, I have a program which searches through a file to find desired information that the user wants, and I am trying to output it in a nice table in JOptionPane to make it easier to read, but I keep getting something like this:
I would like the lines to line up accordingly and be formatted properly, here is the code for that particular message:
String message=String.format("%-10s|%7s|%14s|%13s|%22s", element,symbol,atomicNumber,atomicMass,valence);
JOptionPane.showMessageDialog(null, "Name |Symbol |Atomic Number |Atomic Mass |# of Valence Electrons \n _________________________________________________________________ \n " + message);
Can't seem to figure out what i'm doing wrong here, I used the exact same format code in a different assignment in which it only utilized the terminal and it worked fine, but now that I'm trying to use it in JOptionPane it's not formatting properly.
Any ideas on how to fix this or make it work?

Try JTable instead:
Object[][] rows = {
{element,symbol,atomicNumber,atomicMass,valence}
};
Object[] cols = {
"Name","Symbol","Atomic Number","Atomic Mass", "# of Valence Electrons"
};
JTable table = new JTable(rows, cols);
JOptionPane.showMessageDialog(null, new JScrollPane(table));

The difference between the terminal and your Swing dialog is that the former using a fixed width font, while the latter uses a variable width font. For example: if you look at the picture you posted, you can see that the 'i' is far less wide than the 'm'. That means that a String 15 characters long does not necessarily take up the same space as another String of the same length.
The correct solution to format something like this in Swing is to use either a JTable or a GridBagLayout. If you are happy to use a third party library I recommend looking at DesignGridLayout.
You could also set the font explicitly, but that would still require you to change your code and it would look a bit archaic in the context of a Swing application.

Any ideas on how to fix this or make it work?
In the context of a brute force solution for the JOptionPane you should be able to specify an Array of Objects to be used by the option pane. So the code would be something like:
JLabel[] labels = new JLabel[3];
JLabel heading = new JLabel(...);
heading.setFont( ("monospaced", Font.PLAIN, 12) );
labels[0] = heading;
JLabel line = new JLabel(...);
...
JLabel data = new JLabel(...);
...
JOptionPane.showMessageDialog(null, labels);
This is not a very good solution, but I just wanted to demonstrate the flexibility of JOptionPane to display multiple components organized vertically.
Another option might be to play with the UIManager and change the default font for the option pane. The code would be something like:
Font original = UIManager.getFont("Label.font");
UIManager.put("Label.font", new Font(...)); // specify your monospaced font here
JOptionPane.showMessage(...);
UIManager.put("Label.font", original); // restore default font
I'm not sure if this font applies to all the components on the option pane or just the buttons or just the display components.
The JTable would be the better approach for my money.

Related

How can I create a new line in JTextField to type in?

I want to make a Swing program that writes updates on what you have done. It writes all the information on an uneditable JTextField.
For example:
You have changed the text to BLUE.
You have changed the text to RED.
The problem is that I can't make the two lines separate.
What I get is this:
You have changed the text to BLUE. You have changed the text to RED.
What I've tried is this: (This does not work)
TF_BetInfo.setText(TF_BetInfo.getText() + "\nYou have changed the text to BLUE.");
TF_BetInfo.setText(TF_BetInfo.getText() + "\nYou have changed the text to RED.");
you can't have multiple lines with JTextField , you can use JTextArea for that purpose , and the code wouldn't be much different too , you can still use the same code or you can just
TF_BetInfo.append("\nyou have ...... ");
where TF_Betinfo is a JTextArea rather than a JTextField .
You can't use JTextField for this. JTextField is sinle-line edit control. That is why you got all your output in one line.
If you want several lines to be printed in edit use JTextArea. In your case you can use jTextArea.append(string) (note: jTextArea is an object of class JTextArea, and string is an object of class String).
You can't actually use several lines in a JTextField, but what you can do, is using a JTextArea of the wanted size, and then use the following:
yourJTextArea.setLineWrap(true);
This will automatically detect when the JTextArea needs to use another line and add it, pretty cool, useful and you only need one code line to do it.
JTextArea is more flexible but if you really want flexibility read about JTextPane or JEditorPane, you can show URLS, internet pages and everything that comes to your mind.

Confusion regarding JTextArea and newline character

I'm a bit confused on how the JTextArea works with regards to newline characters. I've got a JTextArea within a JScrollPane object.
JScrollPane scrollPane4 = new JScrollPane();
scrollPane4.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane4.setBounds(66, 155, 474, 133);
getContentPane().add(scrollPane4);
postingArea = new JTextArea();
postingArea.setMaximumSize(new Dimension(470, 200));
postingArea.setLineWrap(true);
postingArea.setBorder(border);
postingArea.setLineWrap(true);
postingArea.setWrapStyleWord(true);
scrollPane4.setViewportView(postingArea);
The text area is used to gather input from the user and post to an SQL database. The string can be read from the database and redisplayed on a separate web page at another time. When a user enters text, the line does wrap, however, what gets entered into the database is one long string. Therefore, what is redisplayed is one long string with a horizontal scroll bar. Is there a way for me to add newline characters at the appropriate location in the text via an event handler? Or, do I simply inform the user to press "Enter" when they want a new line?
I don't see where your TextArea is being added within your ScrollPane. If it were truly being added, the code would have looked like:
JScrollPane scrollPane4 = new JScrollPane(postingArea);
And make your TextArea as:
JTextArea postingArea = new JTextArea(ROWS, COLUMNS);
Where ROWS and COLUMNS are integers specifying the number of rows and columns in the TextArea.
And don't use setBounds() method, but rely on the LayoutManager to do its work as said by #nachokk. Its not a preference, but good practice. Also, since the LayoutManager will do its work, regardless of you setting your component's bounds, if you LayoutManager doesn't consider the custom bounds parameters, it will calculate it on its own, and that's why you are having the issue.
The rest of your code looks fine.
I have resolved this by using the Utilities class. In particular, i called getRowEnd () in a loop to determine the logical end of the line (eg. the point of the word wrap) in the JTextArea. I then inserted the string <br> at that point. The updated string was then inserted into an SQL database and later retrieved and displayed on another page. The text displayed correctly with proper line breaks.

How can I output all values of an array in a single JOptionPane method?

I want to output all the values in a variable in the same sentence in a showMessageDialog method, I know I could use a JList to put them all in one screen, but I'd rather have something like: 3,4,2,62,12,41,5
I could do something like
for(int x = 0;x < array.length;x++){
JOptionPane.showMessageDialog(null,array[x] + ",");}
But that would take more than one screen and it's not what I want.
Also, perhaps it could be done with a JLabel instead, I'll suit myself with that if it's easier.
As shown here, use StringBuilder to construct a line-oriented representation of your array and display it in a JScrollPane in a JOptionPane. The scroll pane's preferred size can be arbitrary.
The problem with this is, if the array is sufficiently large, then it will not fit on the screen anyway. Presenting it in a messagebox may not be usefull to the user.
If you need to show this in a manageable way for arbitrary large arrays, then I would rather write a small dialog class, which is not much work, and then use a scrollable textarea instead.
This way you can prepare it in any way you want to. However, from your short sample it's not entirely clear if you always have a small number of items, in which case creating the string should be sufficient.
Do the concatenation first:
String s = Arrays.toString(array);
s = s.substring(1,s.length-1);
JOptionPane.showMessageDialog(null,s);

Swing Component with automatic line wraping and limited width with HTML support

I want to implement a small tooltip with a scrollbar like the one in eclipse that appears when hovering above a class or member.
The problem I have is finding a way to limit only the width but not the height of a component within the scroll pane I have inside my tooltip. The component should support HTML and also wrap the text correctly when it exceeds the width of the inner bounds, but all components I have tried out have either line wrapping or HTML rendering, but not both
A way to limit only width is also nowhere to be found as every "setXSize" where X is "preferred" "max" "min" etc. all require two arguments and there is no "setMaxWidth" method for components.
Setting "setMaximumSize(new Dimension(256, Integer.MAX_VALUE);" would seem like a solution but it doesnt work as parameters set by "max" and "min" are ignored most of the time which is quite frustrating.
On request a current example of the implementation:
public class MyTooltip extends JTooltip{
private JScrollPane scroll;
private JEditorPane pane;
public MyTooltip(String htmlCode){
this.pane = new JEditorPane();
this.scroll = new JScrollPane(this.pane);
this.pane.setEditable(false);
this.pane.setContentType("text/html");
this.scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//Here the problems begin
this.pane.setMaximumSize(new Dimension(512, Integer.MAX_VALUE));
this.scroll.setMaximumSize(new Dimension(512, Integer.MAX_VALUE));
this.pane.setText(htmlCode);
this.add(scroll);
}
}
the actual code is a bit more complex ofc. but I think this is a good approximation ...
Have you tried JTextPane with HTMLEditorKit (content type text/html)?
I think that's what you need.
Ok, the whole problem just solved itself: One had the idea to let the user write his own texts to be displayed on the tooltips, but that included letting him use multiple "spaces" for indentation when he called for it.
To let HTML render this as intended we replaced every "space" with an & nbsp; so no optimization on gaps between characters would be performed, but this of course has the result that no algorithm for automatic line wrapping would accept any "gap" between words as a suitable place to break the line.
So our implementation actually works as intended, only the Strings we give the tooltip to display are not suitable to be line broken.

A part of Text should be bold in jList

can i set a part of the text in a jList bold?
in some component i can set the text with html-marks to bold but not here.. is there any other way to do this?..
The default font is bold for a JList (in the Metal LAF). So you would first need to change the default font and then add your HTML string to the ListModel to only bold the text that you want displayed bold. Something like:
String[] items = { "one", "<html>normal <b>bold</b> normal</html>" };
JList list = new JList( items );
list.setFont( list.getFont().deriveFont(Font.PLAIN) );
If you have problems then post your SSCCE demonstrating the problem.
You should be able to tie into the ListCellRenderer. Since the DefaultListCellRenderer extends JLabel, I'd expect there to be some way to wedge in HTML that's getting passed over in the default usage.
Have you tried creating a custom list cell renderer yet? If not, you may wish to give this a try. The tutorials will show you how. Please have a look here:
http://download.oracle.com/javase/tutorial/uiswing/components/list.html
http://download.oracle.com/javase/tutorial/uiswing/components/list.html#renderer
http://download.oracle.com/javase/tutorial/uiswing/components/combobox.html#renderer

Categories