How to ensure that text is rendered to fit in tree? - java

JTree does not seem to automatically resize its nodes to accommodate fonts of size 20+. I've tried calling revalidate(), but that doesn't seem to help. The text in the nodes appears "squished" vertically so that the top and bottom of letters are clipped.
How can I use large fonts and ensure that they are displayed properly with a JTree?

Some LAFs (e.g. WindowsLookAndFeel) set a fixed rowHeight which is rather arbitrary (like 16px). Be sure either to force the tree to dynamically compute the height for each node:
tree.setRowHeight(-1);
or calculate the rowHeight based on the tree's font and set that as the fixed height.

Related

How do I resize labels, text fields, etc. in the IntelliJ Java Swing form?

So, for example, I created a text field.
Tried to resize it
But once I release the mouse, it gets back to its original size
So how do I do it? How do I resize elements? And yes, I tried to change the minimum size, maximum size, preferred size but it does not work either, nothing happens.
You can do setLayout(null) on the parent or setPreferredSize on the components, either of which will allow you to resize your Components. But the best answer is to set your Font size to a larger size (setFont(...)) which will cause them to become bigger (have larger values in getPreferredSize) automatically.
JTextField tf = ...;
tf.setFont(tf.getFont().deriveFont(tf.getFont().getSize() * 2));

max size of JLabels being overridden by text width?

I have a JTable in which one column represents the size occupied by a folder on disk. Each row represents one folder, and this column has a list of rectangles; the width of each rectangle represents a percentage of the size occupied by one type of file. Here's a picture:
I do this by creating a JLabel for each file type in a row, then, in the getTableCellRenderer() method, I have an array of JLabels, one per file type. That method sets the preferred and maximum sizes of the JLabel to be the column height and the percentage of the column width for each label.
My problem comes when the picture is narrowed; the following was made by narrowing the frame of the program illustrated above:
As you can see, the percentage representation is gone, and the width of the JLabels now appear based on the width of the text, not on the preferred/max sizes set. If I narrow the window further, the percentage calculations again appear to take precedence; it is only in a narrow width range that I see this behavior.
Is there another way to do this? Do I have to draw rectangles and use drawText() instead of using the FlowLayout and text elision that already exists?
Here's the code that sets the characteristics of the JLabels:
sizeBlockDimensions[i].setSize(newWidth, rowHeight);
sizeBlockLabels[i].setPreferredSize(sizeBlockDimensions[i]);
sizeBlockLabels[i].setMaximumSize(sizeBlockDimensions[i]);
sizeBlockLabels[i].setBackground(color);
sizeBlockLabels[i].setText(labelText);
sizeBlockLabels[i].setVisible(true);
i++;
instead of using the FlowLayout
You should be able to use the Relative Layout. It was specifically designed for relative sizes and should adjust automatically as the space available changes.

Make java scrollbar start in middle of the scrolling content

I have a horizontal scrollbar that controls a large panel (with a very large width, and a very small height, thus an horizontal panel).
I want the start of the scrollbar (when the knob is at max left) NOT to start at the beggining of the panel it is scrolling, but rather in a specific place that I dictate. The same for the end of the scrollbar (when the knob is at max right).
I find that the scrollbar is always bound to the panel it is scrolling, and I can't figure out how to change its behaviour.
EDIT:
As an example, picture a normal web-page: when at the top of the page, the scrollbar knob is also at the top. When at the bottom, the scrollbar knob is at the bottom. I want to define new limits for the content, such that when the scrollbar knob reaches the top or bottom, the page is showing the limit I defined, instead of the real top and bottom.
As shown in How to Use Scroll Panes, you can use the component's scrollRectToVisible() method to scroll to an arbitrary Rectangle. There's an example here.
Addendum: As a Container, a JPanel is fairly fungible even if it has considerable nested content. One reliable way to swap content at a given level is via CardLayout, shown here, here and here.
I solved the problem by using the JScrollbar method setValues(), which allows me to set at the same time the maximum, minimum, value and extent of the scrollbar. By setting the maximum and minimum to the values I want, the scrollbar behaves as I wanted/expected.
The problem was that I was only setting maximum and minimum values (setMaximum, setMinimum), and since there is a strict policy at the model that minimum <= value <= value+extent <= maximum, that estrategy did not work.
Would it be possible to keep the large panel as a backing store and copy the region of interest into a panel which is actually realized in the scrollpane. This way you don't have to fight the behavior of the scrollpane.

In Java, How to draw multi-line text with auto-resizing font that must fit into a bounds

Using TextLayout and LineMeasurer (The only way to draw multiline center-aligned text in java), How does one go about this?
Use a JTextPane. You can set the paragraph attributes to "centered" and every line will be centered within the text pane. After you create the text pane you can do something like:
SimpleAttributeSet center = new SimpleAttributeSet();
StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
doc.setParagraphAttributes(0, doc.getLength(), center, false);
Hey camickr, I don't think this solution properly handles the auto-resizing of fonts to fit within bounds.
I am essentially drawing text to a JScreen (Windowless form of a Jframe) for text projection reasons, and I need whatever text that is in there to conform to the bounds of the screen, no matter what font size was initially set, so it auto-adjusts font size as neccessary.
Center alignment really isn't the problem here. I can do center aligned on my own without the JTextPane. The problem is the font fitting within bounds.
I didn't want to have to loop through and check textlayout bounds each time after a get from linemeasurer and minimize font size till it's just right, but it seems would be the only way to go about it.
So I created a wrapper class around LineBreakMeasurer, which immediately populates an arraylist of TextLayouts upon instantiation of the wrapper class. While generating this array list of layouts, I got the lineheight of each layout and added that incrementally to a total line height. I can then externally query this wrapper for the total lineheight of all it's text and if it is greater than my vertical bounds, I rederive the font with a lesser font size and repopulate the arraylist of layouts....which can then be gotten from the arraylist using some getNextLayout() method.
I also had this wrapper class force '\n' to be respected by lineBreakMeasurer by doing a String [] lines = text.split("\n")
And then running linebreakMeasurer on each of those lines as I populated the arraylist of layouts.

GridBagLayout manager and resizing controls

I'm not sure if GridBagLayoutManager is the only layout manager that does this, but here is my problem. I have 4 controls layed out horizontally in a GridBagLayout. To keep things simple for this example, each control get's an equal 1/4 of the form, and each control resizes with the same ratio as the other controls. The four controls are JTextField's where each text field maps to a column in a record from a ResultSet. Additional controls on the form allow one to navigate through the records.
If I navigate from one record to the next, then the text fields update their text to show the new data. However, the text fields also get automatically resized in proportion to the amount of text they are showing... text fields with a large amount of data expand in size, and text fields with a smaller amount of data get squished. If I run through 10 records in a ResultSet, then the controls are always resizing themselves and it looks quite bizarre to say the least.
What I would like to do is prevent these controls from resizing, unless (and until) the underlying container gets resized. So if I resize the window, then I would like the controls to resize (according to the "weight x" variable in the Layout), but I don't want the controls to resize just because the amount of text they are showing becomes more or less.
Anybody have any ideas here?
For JTextField (as mentioned in the contents) call setColumns(int) to set a preferred size on the text.
For JComboBox, call setPrototypeDisplayValue(Object) which will cause that value to be rendered and the preferred size of the JComboBox will be set based on that value.
In general, you can call setPreferredSize(Dimension) on any component directly to get the same behavior. General if not set the value is calculated based on some defaults on the component. What is happening with JTextField, JComboBox, and most JTextComponent derivatives. is that the preferred size on those components is driven by values the user is capable of changing (the text values, the combobox selection). Whereas with most other component (JButton, JCheckBox, etc) the content size doesn't really change when the user acts on it. Setting the columns and rows and the prototype display value fixes the value used to calculate the preferred size.

Categories

Resources