Why my JScrollPane is different from the example? - java

I'm trying to learn a bit of Swing and i'm trying 14.46.2.Add component to JScrollPane example. The code is this:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.border.LineBorder;
public class AddingToJScrollPane {
public static void main(String args[]) {
JFrame frame = new JFrame("Tabbed Pane Sample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("Label");
label.setPreferredSize(new Dimension(1000, 1000));
JScrollPane jScrollPane = new JScrollPane(label);
JButton jButton1 = new JButton();
jScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
jScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane.setViewportBorder(new LineBorder(Color.RED));
jScrollPane.getViewport().add(jButton1, null);
frame.add(jScrollPane, BorderLayout.CENTER);
frame.setSize(400, 150);
frame.setVisible(true);
}
}
From the page you can see what is the expected result.
However, just copy&pasting that code, I get the result in the image below. I'm trying to understand if the example is out of date or the example image is wrong (where's the red border on the tutorial image?). Moreover, my scrollbars are not enabled whiley I'm expecting that they are. Am i missing something to get them enabled (in the tutorial they are ok)? I'm using JDK7.

It is OK to see the red border, it is caused by this line:
jScrollPane.setViewportBorder(new LineBorder(Color.RED));
As a background info, you should be aware that setting a colored line border to components is a useful debugging possibility in Swing (otherwise it is often hard to see where one component ends and another starts), so here the author probably wanted to debug something after taking the screenshot, and forgot to remove this line from the code.
BTW, if you want to learn Swing, the best online resource is the "official" one: http://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html
EDIT: the scrollbars are enabled, it is not like they are "greyed out", there is a visual change if you click on the arrows. There is nothing to scroll, because the button is always resized to the size of the visible area. As I said, this is not a good example, don't learn from here...

The code is ok and the bordar is Red
jScrollPane.setViewportBorder(new LineBorder(Color.RED));
and the image in the link is wrong image

Related

A color object not working as a color unless recreated

I'm struggling with a descriptive title.
I'm trying to use the swing.plaf colors from NimbusLookAndFeel in a custom component of mine.
The colors i'm getting from UIManager looks good, but the setBackground and setForeground methods doesn't work with the colors im getting.
The following sample displays the very curious behaviour
package syscolorbug;
import java.awt.Color;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class SysColorBug {
public static void main(String[] args) throws Exception {
javax.swing.UIManager.
setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
Color background = javax.swing.UIManager.getDefaults().
getColor("List[Selected].textBackground");
JFrame jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLayout(new FlowLayout());
jf.setSize(400,300);
JLabel l = new JLabel("Text");
l.setOpaque(true);
jf.add(l);
System.err.println(background);
// This needs to happen for the color to be set.
//24: background = new Color(background.getRGB());
System.err.println(background);
l.setBackground(background);
jf.setVisible(true);
}
}
If i comment out 24: it works as intended.
The debug output on background shows
DerivedColor(color=57,105,138 parent=nimbusSelectionBackground offsets=0.0,0.0,0.0,0 pColor=57,105,138
and
java.awt.Color[r=57,g=105,b=138]
Further investigations shows that the problem doesn't seem to be affecting other LookAndFeels.
For instance on the Metal LAF produces
javax.swing.plaf.ColorUIResource[r=255,g=255,b=255]
for the 'List.background' key.
Is this a bug in the Nimbus plaf?
I'd very much like to avoid the superflous background = new Color(background.getRGB()); is there an easy fix?
Java version is openjdk java 1.8.0.
I don't do laf much when I do graphics so I don't understand why List[Selected].textBackground would be the background of the JLabel. The default appears to be color=214,217,223
This also seems to match what I saw and read at nimbus laf

Swing not antialiasing correctly

I have a frame with a very standard JLabel.
No matter how big the font, or how small/big the JLabel, the text is always sharp.
I'd like for it to be antialiased.
Looking up on so, I found a few questions but no solutions.
Using this answer:
Anti-aliased JLabel
I understood that it's useless to set the hints.
I have also tried to no avail:
String property = "swing.aatext";
if (null == System.getProperty(property))
System.setProperty(property, "true");
And here's the screenshot of the text, font Comfortaa, size 90:
The same problem comes with all fonts and sizes I have tried so far.
Am I missing out on some way to enable the antialiasing?
I have not changed the JLabel in any way, added custom graphics, code, or anything at all. It's a black JPanel on a JFrame, with a JLabel in the middle.
FAQ:
Java 8
Run from Eclipse 4.1
Window 10
Both on 4k and FHD Screen
Nimbus
Both with decorated and undecorated frames
Both with black and transparent background
Font installed on windows, not loaded as resource
Same behaviour with any font
I have used swing in the past, same machine, same version of everything, no issues that I can remember
Am I doing something wrong? Any ideas?
MCVE: ---> The code is mine, I just changed the font because you might not have Comfortaa installed.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class TestFrame extends JFrame {
private JPanel panel;
private JLabel mcveLabel;
private JLabel mcveLabel2;
public TestFrame() {
setSize(374, 153);
setLocationRelativeTo(null);
setDefaultCloseOperation(3);
panel = new JPanel();
panel.setBackground(Color.BLACK);
getContentPane().add(panel, BorderLayout.CENTER);
panel.setLayout(new BorderLayout(0, 0));
mcveLabel = new JLabel("Antialias");
mcveLabel.setFont(new Font("Arial", Font.BOLD, 60));
mcveLabel.setHorizontalAlignment(SwingConstants.CENTER);
mcveLabel.setForeground(Color.WHITE);
panel.add(mcveLabel, BorderLayout.CENTER);
mcveLabel2 = new JLabel("NEEDED");
mcveLabel2.setFont(new Font("SansSerif", Font.PLAIN, 30));
mcveLabel2.setForeground(Color.GREEN);
mcveLabel2.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(mcveLabel2, BorderLayout.SOUTH);
setVisible(true);
}
public static void main(String[] args) {
new TestFrame();
}
}
EDIT:
Added screen with the same font as the MCVE.

Added components are not painted until parents are repainted from another source

When I modify a component in a component tree of any depth, the modifications usually show automatically, immediately, without need for me to take any action to that end.
Not so when the modification is an addition of a new child.
Furthermore, if I want to force the repaint using any of the methods appropriate (as far as I understand the API), this has no tangible effect as well.
Only when a new modification to the existing tree - including the added, but still invisible component - is made, does the added child appear.
Here is an example, that will render a black window with an "Add" button at the bottom. Clicking the button will have no effect. Resizing or minimising the window will cause as many white "XX" strings to appear, as the button has been pressed beforehand.
I would, of course, very much like to have the additions appear immediately one by one, whenever the button is pressed.
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Applikation
{
public static void main(String[] argumente)
{
Box dummy = new Box(BoxLayout.Y_AXIS);
JFrame window = new JFrame();
JPanel panel = new JPanel();
panel.setBackground(Color.black);
window.add(dummy);
dummy.add(panel);
JButton button = new JButton("Add");
button.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e)
{
JLabel white = new JLabel("XX");
white.setBackground(Color.white);
white.setForeground(Color.white);
panel.add(white); // only visible after resizing window or switching focus to another program and back
panel.invalidate(); // does nothing
panel.repaint(); // does nothing
panel.repaint(200); // does nothing
} });
dummy.add(button);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}
}
What am I missing?
Note that this is essentially a duplicate of this question, but as can bee seen in my example code, none of its answers do apply: They empirically do not work.

How To Add JLabel to Already Existing Jframe?

lol i dont even know if i worded that right
i am a really new programmer and this is my code for the main class:
package culminatingnew;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class CulminatingNew {
public static void main(String[] args) {
Container container = null;
JFrame jframe = new JFrame("Math Adventure");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setLocationRelativeTo(null);
jframe.setBounds (150, 0, 1000, 1000);
jframe.setBackground(Color.blue);
jframe.setVisible(true);
JLabel labelText = new JLabel("Welcome!");
jframe.getContentPane().add(new CharacterChoose());//
jframe.setVisible(true);
jframe.getContentPane().add(labelText);
jframe.setVisible(true);
So basically, I'm making a game. In another class in the assignment package is CharacterChoose, where the user is greeted with a picture of their character. All I want to do is add text to this same screen saying "Welcome", but whenever I try this it just ignores the CharacterChoose screen and opens a new blank frame that says "Welcome". Is there any way to fix this?
GUI's are not linear/procedural programs, the are event driven, that is, something happens and you respond to it.
Instead, maybe consider using a button saying "Continue" or something, which the user must press, once pressed, you can then present the next view.
I'd recommend having a look at CardLayout for easier management of switching between views.
See How to Use Buttons, Check Boxes, and Radio Buttons, How to Write an Action Listeners and How to Use CardLayout for more details

why is my JLabel not producing an image?

I have gone over several tutorials and was wondering why my JLabel is not producing an image? I thought I had everything where I should be for the image to be displayed. Is it possible other graphics in my program are interfering? Is there any top-down layer system java uses to determine which images are on top of each other if you have multiple ones on top of each other??
package scratch;
import java.awt.Font;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JLabel;
//import statements
//Check if window closes automatically. Otherwise add suitable code
public class okay extends JFrame {
JPanel jp = new JPanel();
JLabel jl = new JLabel();
public okay(){
jl.setIcon(new ImageIcon("C:\\Users\\ShawnK\\Desktop\\cat.png"));
jp.add(jl);
add(jp);
validate();
}
public static void main(String args[]) {
JFrame window = new JFrame();
okay t1 = new okay();
window.setSize(640,800);
window.setTitle("lets do this");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );
window.setVisible(true);
drawingComponent DC = new drawingComponent();
ai enemy = new ai();
window.add(DC);
window.add(t1);
}
}
You're just creating a plain vanilla JFrame:
JFrame window = new JFrame();
and you never create a new okay() object. Understand that it will not create itself by magic, and if you want it displayed, you have to do this in code.
As an aside, I have no idea in creation what a drawingComponent is:
drawingComponent DC = new drawingComponent();
since you never show the class code. Also you shouldn't set a JFrame visible until all the components have been added.
Also
Learn and follow Java naming conventions as doing this will help others (us!!) better understand your code. Variable names should all begin with a lower case letter while class names with an upper case letter.
Avoid extending JFrame. While this may be OK for trivial programs such as this, it does not scale well, meaning it makes your code more complicated and paints you in the corner in even slightly larger or more complex programs.
Instead gear your GUI's toward creating JPanels, panels that then can be placed in JFrames if desired, or JDialogs, or JOptionPanes, or other JPanels. This will give your code much greater flexibility.
Again, don't call setVisible(true) on a JFrame until all initial components have been added.
Yes, you're better off getting your image as a BufferedImage using ImageIO.read(...) and then placing this into your ImageIcon. It's a bit safer and (I think) allows for better caching of images.

Categories