Java text component calculate its own preferred size - java

I am making a customised swing component and I have hit a problem. I want a simple text display (like a jlabel) that changes colour over time. Currently I have extended JPanel and overridden paintComponent(Graphics) to create a component that can draw the text it's given and cycle the colours as required. However, I do not know how to make it always draw the text in the centre of the component, nor how to make it calculate its own default preferred size (as I do not know the exact dimensions of the text) e.g. a JLabel with text set automatically returns the right value for getPreferredSize and the text always fits neatly into the label, this is the functionality I am looking to emulate. Does anyone know how to achieve this?

The FontMetrics class is used to determine the geometry of rendered text with a specific font. This will tell you how much space you need to render your text.
Take a look at the getLineMetrics methods.

Related

How do I change the color of an actual JButton in Java? Not the background and not the text

button[currRow][currCol].setBackground(Color.RED);
button[currRow][currCol].setContentAreaFilled(true);
button[currRow][currCol].setOpaque(true);
That's what I have right now for my connect four game to denote a red player's move.
At the moment, it only colors the background and if I change my code to button[currRow][currCol].setForeground(Color.RED) then the whole thing just appears to not change. How would I fix this?
This is not easily achievable. The problem is that the pluggable look and feel paints the button content, and it does so in whatever way it sees fit. For instance, some L&F might paint a gradient which does not use the background color.
I suggest for a case such as yours to use a custom image (JButton.setIcon()) and no content area (JButton.setContentAreaFilled(false)).
Alternatively, you could create a custom component which draws the element itself, overriding JComponent.paintComponent().

Using a paintComponent with layout

How do I convert a paintComponent to something that I can manipulate with a layout in a JFrame?
So, I'm running into an issue. I haven't really been taught (and don't have access to a book) how to use layouts/GUI stuff in my courses yet.
My issue is this: I have a program that the user inputs a number. Based on this number, the program calculates a circle and draws it out with a paintComponent method that has a for loop inside of it. The "pixels" that the circle is drawn with are actually fillRect methods. The current method of getting a user-input that I am using is a JOptionPane showInputDialog. This is MOSTLY fine, but I want the user to be able to select from a set of pre-defined numbers. Somebody suggested that I use a JComboBox, but I don't know how I would convert the paintComponent to something that would be usable by a layout manager (which a JComboBox must use, as far as I've learned). I know the dimensions of the paintComponent (805px by 805px) and there is no situation where it will change. If I could get some help with this bit, I am confident that I can figure out using a layout manager myself.
Another way to paint (besides custom painting) is to paint to a BufferedImage. The image can then be displayed in a JLabel.
Examples:
Painting in a BufferedImage inside Swing A fairly complicated one.
Dynamic Graphics Object Painting Another one.
Yet another one.
You don't know the dimensions of paintComponent because it's a method, and methods don't have dimensions. You probably know the dimensions of a JPanel or a JFrame or whatever your component is.
You should separate the panel where you do the painting, and a different panel which would contain any comboboxes or other inputs you decide to put in. That way you can keep your drawing panel as is, and they won't interfere with each other. You'll want to search for the tutorial on LayoutManagers.

How can I add buttons on a picture?

I am currently creating a GUI for a game. I am currently loading an image using JLabel onto my JPanel, I was wondering whether it would be possible to add buttons on various parts of the image e.g. (5,7) and (12,12).
If you wish to have JButtons appear over your image, a better approach would be to override the paintComponent of the JPanel and use drawImage to draw the image similar to this example . This will allow you to add components to the container.
Absolute positioning(null layout) is generally frowned upon for setting component locations, however. This DragLayout should be a better substitute taking care of component sizing.
DragLayout was designed to replace a null layout. It will respect the location of a component. By default it will use the preferred size of the component to determines its size. Finally, it will automatically calculate the preferred size of the Container.

Need help about drawing on JTextPane

I'm using JTextPane and JButton
If I click the Button, I hope every characters in JTextPane will have a dot under it
Is there any way to do this?
The big problem is how to add dots under every characters :(
You can make use of javax.swing.text.DefaultHighlighter, which handles character spacing of a text component in order to do background painting on that component.
public class DotHighlighter extends DefaultHighlighter {
// implementation
}
Implementing a custom highlighter is a moderate sized amount of work, but here's a nice code example of an underlining highlighter implementation; you should be able to modify it to draw dots.
http://java-sl.com/tip_colored_strikethrough.html you can use the example of colored strikethrough.
All you need is to draw your line under letters. Just set Stroke to your Graphics2D instance. (See BasicStroke and dash pattern)
Are you using a monospaced font? If so, it would be possible to create a new label and display a string that is composed only of periods (of the same length as the string in the original label), and display that label a bit lower than the first.
I.E., if your label says 2446, then you could make a second label that's 5 or 10 pixels lower, which says .....
Again, this will only work with a monospaced font- for any other fonts, it would still be possible, but it would involve a more complicated solution (looping through each character, finding its location, and then managing to display a dot beneath it), I believe.

Java sampling pixel color in swing

I have to create a special TextFieldUI that draws an image as the background. That image contains some alpha components. However, whenever a character is written in that text field, first it redraws the background and then draws the character. This is fine when the background contains no alpha components, but after a few characters have been typed, the alpha areas sum up to become black.
The only way I can see around this is in the paintBackground method of TextfieldUI (which I'm overriding), I have to first sample the color of the background at that location, paint the entire graphics component that color, and then paint my background.
Does anyone know how to sample the color of a pixel when all I have access to is the Graphics object?
Is there a better way to draw a custom image as the textfield background other than overriding paintBackground in TextfieldUI?
Thanks
I haven't tried it before, but Swing is built on top of AWT, and the Robot class had a way of sampling specific pixels in the AWT
Well, I don't know what your custom code looks like in the paintBackground method, but I would make sure you fill in the text field background before you draw the image.
I'll let you decide if its "better" or not, but you can use the Background Panel which allows you to add an image to a panel. Then you add the text field to the panel (the text field is automatically made non-opaque so the image shows through). Then you add the panel to the GUI.
If that doesn't work then it would be nice to have a demo of your code so we can see whats actually happening.
When you override paintBackground, you're calling the superclass version first, right? It already lays down a background-color rectangle that would give your image a fresh-start.
Rather than 'sampling' the background color, it's probably already correct (the superclass paintBackground code gets it from the parent component if not locally set). If that default is not correct, set it in initial interface construction. (Your field isn't being overlaid on other complicated arbitrary interface of unknown solid colors, is it?)

Categories