How to put JPanel in JScrollpane? - java

i want to put JPanel in JScrollpane i wrote this code but it didn't work
so i need your help
centerPanel_scroll = new JScrollPane();
centerPanel_scroll.setBounds(261, 71, 750, 698);
center_panel = new JPanel();
center_panel.setLayout(null);
center_panel.setBackground(Color.cyan);
centerPanel_scroll.setViewportView(center_panel);
main_panel.add(centerPanel_scroll);

Your center_panel is in the JScrollPane. The viewport doesn't respect size/bounds but rather preferred size, so if you must, set the preferred size via setPreferredSize(...), or even better, have the component extend getPreferredSize().
I have no idea what you're trying to achieve via setBounds position at 261, 71. That's position within the viewport so it makes no sense whatsoever.
Also you're potentially messing yourself up with your use of the null layout which JScrollPanes can have a great deal of trouble with . Just don't set bounds/sizes or use null layouts and you'll find life a lot easier.
e.g.,
centerPanel_scroll = new JScrollPane();
// centerPanel_scroll.setBounds(261, 71, 750, 698);
center_panel.setPreferredSize(new Dimension(750, 698));
center_panel = new JPanel();
// center_panel.setLayout(null);
center_panel.setPreferredSize(new Dimension(900, 800));
center_panel.setBackground(Color.cyan);
centerPanel_scroll.setViewportView(center_panel);
main_panel.add(centerPanel_scroll);
e.g.,
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.*;
public class ScrollEg extends JPanel {
public ScrollEg() {
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(new InnerPanel());
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(650, 500);
}
private static class InnerPanel extends JPanel {
private static final int PREF_W = 1000;
private static final Color COLOR_1 = Color.RED;
private static final Color COLOR_2 = Color.BLUE;
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_W);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(new GradientPaint(0, 0, COLOR_1, 100, 100, COLOR_2, true));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.fillOval(0, 0, PREF_W, PREF_W);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
ScrollEg mainPanel = new ScrollEg();
JFrame frame = new JFrame("ScrollEg");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}

Related

JComponents with Graphics.draw

I am trying to make a simple game using JPanel.
I am using Graphics Draw to display all information, including text, but I need to add user input.
I was thinking about using JTextField with absolute positioning to make it work with what is being drawn, but I have heard that absolute positioning is not a good way set up a JPanel.
Is there a better way to use both graphics paint and JComponents in the same panel?
Solution: use layout managers
Why not simply have the drawing JPanel held by another JPanel, one that uses BorderLayout and held in the BorderLayout.CENTER position. You can then place JTextFields or other control components in the outer JPanel in other positions.
You can also add a layout manager to the drawing JPanel and then add components onto this using the layout. Just remember that if you add any JPanels on top of the drawing JPanel, the added JPanels should be transparent, that is myPanel.setOpaque(false) should be called on them so that the drawing underneath shows through.
For example -- run this program to see what I mean:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class GradientPaintEg extends JPanel {
private DrawingPanel drawingPanel = new DrawingPanel();
private JSlider hue1Slider = new JSlider(0, 100, 0);
private JSlider hue2Slider = new JSlider(0, 100, 0);
public GradientPaintEg() {
Color color = drawingPanel.getColor1();
float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
int value = (int) (hsb[0] * 100);
hue1Slider.setValue(value);
color = drawingPanel.getColor2();
hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
value = (int) (hsb[0] * 100);
hue2Slider.setValue(value);
hue1Slider.setMajorTickSpacing(20);
hue1Slider.setMinorTickSpacing(5);
hue1Slider.setPaintTicks(true);
hue1Slider.setPaintLabels(true);
hue1Slider.setPaintTrack(true);
hue1Slider.addChangeListener(new SliderListener(hue1Slider, drawingPanel, true));
hue1Slider.setOpaque(false);
hue2Slider.setMajorTickSpacing(20);
hue2Slider.setMinorTickSpacing(5);
hue2Slider.setPaintTicks(true);
hue2Slider.setPaintLabels(true);
hue2Slider.setPaintTrack(true);
hue2Slider.addChangeListener(new SliderListener(hue2Slider, drawingPanel, false));
hue2Slider.setOpaque(false);
JPanel sliderPanel = new JPanel(new GridLayout(0, 1, 4, 4));
sliderPanel.add(hue1Slider);
sliderPanel.add(hue2Slider);
sliderPanel.setOpaque(false);
setLayout(new BorderLayout());
// if you want to add the slider panel to the main JPanel:
// add(sliderPanel, BorderLayout.PAGE_START);
add(drawingPanel);
// if you want to add the sliderPanel to the drawing JPanel
drawingPanel.setLayout(new BorderLayout());
drawingPanel.add(sliderPanel, BorderLayout.PAGE_START);
}
private class SliderListener implements ChangeListener {
private JSlider slider;
private DrawingPanel drawingPanel;
private boolean color1Listener;
public SliderListener(JSlider slider, DrawingPanel drawingPanel, boolean color1Listener) {
this.slider = slider;
this.drawingPanel = drawingPanel;
this.color1Listener = color1Listener;
}
#Override
public void stateChanged(ChangeEvent e) {
int value = slider.getValue();
float hue = value / 100f;
Color c = Color.getHSBColor(hue, 1f, 1f);
if (color1Listener) {
drawingPanel.setColor1(c);
} else {
drawingPanel.setColor2(c);
}
}
}
private static void createAndShowGui() {
GradientPaintEg mainPanel = new GradientPaintEg();
JFrame frame = new JFrame("GradientPaintEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class DrawingPanel extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private static final float X2 = 20;
private static final float Y2 = X2;
private Color color1 = Color.RED;
private Color color2 = Color.BLUE;
public Color getColor1() {
return color1;
}
public void setColor1(Color color1) {
this.color1 = color1;
repaint();
}
public Color getColor2() {
return color2;
}
public void setColor2(Color color2) {
this.color2 = color2;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(new GradientPaint(0, 0, color1, X2, Y2, color2, true));
g2.fillRect(0, 0, getWidth(), getHeight());
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
}
In this code example, I have a JPanel that draws, called class DrawingPanel and use within another main JPanel, the GradientPaintEg class:
public class GradientPaintEg extends JPanel {
private DrawingPanel drawingPanel = new DrawingPanel();
If I want to add components to the DrawingPanel, I first give it a layout, and then add the component(s). For instance, there is a JPanel that holds JSliders called sliderPanel that I add to the DrawingPanel instance using BorderLayout:
drawingPanel.setLayout(new BorderLayout());
drawingPanel.add(sliderPanel, BorderLayout.PAGE_START);
This adds the sliderPanel to the top of the drawingPanel.
But also note that I have to make sliderPanel non-opaque first:
JPanel sliderPanel = new JPanel(new GridLayout(0, 1, 4, 4));
sliderPanel.add(hue1Slider);
sliderPanel.add(hue2Slider);
sliderPanel.setOpaque(false);
I've also made the JSliders themselves non-opaque so that the underlying drawing shows through:
// ......
hue1Slider.setOpaque(false);
// ......
hue2Slider.setOpaque(false);
Here is a basic mcve of combining user input in JTextfield and painting, on a panel using a layout manager:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
class DrawingPanel extends JPanel {
private final JButton update;
private final JTextField input;
private final static int W = 300, H = 350, RADIUS = 100, GAP = 50;
private String text;
public DrawingPanel() {
setPreferredSize(new Dimension(W, H));
setOpaque(false);
setLayout(new BorderLayout());
update = new JButton("Update");
update.addActionListener(e->update());
add(update, BorderLayout.PAGE_START);
input = new JTextField();
add(input, BorderLayout.PAGE_END);
text = "Enter text and press button";
}
private void update() {
text = input.getText();
input.setText("");
repaint();
}
#Override
public void paintComponent(final Graphics g) {
super.paintComponents(g);
final int width = getWidth();
final int height = getHeight();
g.setColor(Color.RED);
g.fillOval(width/2 - RADIUS, height/2 - RADIUS, RADIUS*2, RADIUS*2);
g.setColor(Color.BLUE);
g.drawString(text, height/2 - RADIUS - GAP, GAP);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(()->makeGui());
}
private static void makeGui() {
JFrame frame = new JFrame();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(new DrawingPanel());
frame.pack();
frame.setVisible(true);
}
}

Set Transparent Color for the Whole JPanel

I have a JPanel with a JLabel which owns an Icon picture.
how do I set a transparent red color at the top of the whole JPanel (including JLabel Icon)?
I have the transparent backgriound color on for the panel but I want the whole panel including the picture and everything get this transparent color. something like a transparent colorful glass at the top of the JPanel
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class TransparentJLabel {
private static final String IMAGE_PATH = "http://duke.kenai.com/Oracle/OracleStratSmall.png";
private static void createAndShowUI() {
JPanel panel = new JPanel();
panel.setBackground(Color.pink);
URL imageUrl;
try {
imageUrl = new URL(IMAGE_PATH);
BufferedImage image = ImageIO.read(imageUrl);
ImageIcon icon = new ImageIcon(image);
JLabel label = new JLabel(icon);
panel.add(label);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
JFrame frame = new JFrame("TransparentJLabel");
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
If you just need a layered panel over the whole contentPane, a simple glassPane will do fine (override it's paintComponent(...) method). For example:
JPanel glassPane = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(new Color(0, 100, 0, 100));
g2.fillRect(0, 0, getWidth(), getHeight());
g2.dispose();
}
};
glassPane.setOpaque(false);
frame.setGlassPane(glassPane);
frame.getGlassPane().setVisible(true);
However, if you want a layered panel over only one JPanel, I would use JLayer combined with LayerUI, as MadProgrammer already mentioned. You will need a custom LayerUI in which you override the paint(Graphics g, JComponent c) method. I know that sounds dangerous, but I honestly don't know of another way of doing it...
I've provided an example below, this is the output:
As you can see, panel1 (or more accurately, the JLayer) is slighty transparent (RGBA = "0, 100, 0, 100") and panel2 is normal.
Code:
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.plaf.LayerUI;
public class Example {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Example();
}
});
}
public Example() {
JFrame frame = new JFrame("Example");
JPanel panel1 = new JPanel();
panel1.add(new JButton("Panel 1"));
MyLayerUI layerUI = new MyLayerUI();
JLayer<JPanel> panel1Layer = new JLayer<JPanel>(panel1, layerUI);
panel1.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
if (layerUI.hasOverlay()) {
layerUI.setOverlay(false);
} else {
layerUI.setOverlay(true);
}
panel1Layer.repaint();
}
});
JPanel panel2 = new JPanel();
panel2.add(new JButton("Panel 2"));
JPanel contentPane = new JPanel(new GridLayout(2, 1));
contentPane.add(panel1Layer);
contentPane.add(panel2);
frame.setContentPane(contentPane);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class MyLayerUI extends LayerUI<JPanel> {
private boolean overlay = true;
#Override
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
if (hasOverlay()) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(new Color(0, 100, 0, 100));
g2.fillRect(0, 0, c.getWidth(), c.getHeight());
g2.dispose();
}
}
public boolean hasOverlay() {
return overlay;
}
public void setOverlay(boolean overlay) {
this.overlay = overlay;
}
}

Unable to add other components to window after creating background using JLabel in Java

I want to create a java Application like a widget. Here is my code below
package newpackage;
public class MainFrame extends JFrame {
JLabel imageLabel = new JLabel();
public MainFrame() {
try {
this.setUndecorated(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(new Dimension(360, 360));
ImageIcon ii = new ImageIcon(this.getClass().getResource("imageexcel.gif"));
imageLabel.setIcon(ii);
add(imageLabel, java.awt.BorderLayout.CENTER);
this.setVisible(true);
Shape shape=new Ellipse2D.Float(0,0,360,360);
AWTUtilities.setWindowShape(this, shape);
AWTUtilities.setWindowOpaque(this, false);
imageLabel.add(new JButton("START"));
} catch (Exception exception) {
exception.printStackTrace();
}
}
public static void main(String[] args) {
new MainFrame();
}
}
In the above code, I have done the following:
Created a Frame
Removed the Title Bar
Added the Background using JLabel
Changed the shape of window as circle according to the shape of image
Now I would like to add some components in to it and perform some action with them but no component is visible after adding.
I have tried adding to Frame as well as JLabel and no use from either.
This is the image i used for background
Please help me to proceed further....
Thanking you
JLabels use null layouts by default, and so your button will default to size 0,0. Try giving it a decent layout manager, even FlowLayout would likely work. Another solution is to keep the null layout and set the sizes and positions of added components, but this route is a dangerous route and one I don't recommend.
Actually a GridBagLayout works nice to center the components. Also add all components before calling setVisible(true):
imageLabel.setLayout(new GridBagLayout());
this.setUndecorated(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(new Dimension(360, 360));
ImageIcon ii = new ImageIcon(this.getClass().getResource("imageexcel.gif"));
imageLabel.setIcon(ii);
add(imageLabel, java.awt.BorderLayout.CENTER);
imageLabel.add(new JButton("START"));
this.setVisible(true);
or better?
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Shape;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.geom.Ellipse2D;
import java.net.URL;
import javax.swing.*;
import com.sun.awt.AWTUtilities;
#SuppressWarnings("serial")
public class MainPanelOvalFrame extends JPanel {
private static final String RESOURCE_PATH = "imageexcel.gif";
private Window window;
private Image img;
public MainPanelOvalFrame(Window window, Image image) {
this.window = window;
this.img = image;
setLayout(new GridBagLayout());
add(new JButton(new StartAction("Start", KeyEvent.VK_S)));
int w = image.getWidth(this);
int h = image.getHeight(this);
Shape shape = new Ellipse2D.Float(0, 0, w, h);
AWTUtilities.setWindowShape(window, shape);
AWTUtilities.setWindowOpaque(window, false);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || img == null) {
return super.getPreferredSize();
}
int w = img.getWidth(this);
int h = img.getHeight(this);
return new Dimension(w, h);
}
private class StartAction extends AbstractAction {
public StartAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
window.dispose();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame();
frame.setUndecorated(true);
URL imgUrl = MainPanelOvalFrame.class.getResource(RESOURCE_PATH);
Image image = new ImageIcon(imgUrl).getImage();
MainPanelOvalFrame mainPanel = new MainPanelOvalFrame(frame, image);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
You just need to set a Layout manager for imageLabel ,or use null as the Layout manager, then set the size and location of the JButton manually.
to use Layout Manager
imageLabel.setIcon(ii);
imageLabel.setLayout(new FlowLayout());
imageLabel.add(new JButton("START"));
//need to setLayout and add JButton before setVisible(true)
add(imageLabel, java.awt.BorderLayout.CENTER);
this.setVisible(true);
to use null layout
JButton j=new JButton("START");
j.setSize(100,50);
j.setLocation(imageLabel.getWidth()/2-j.getWidth()/2, imageLabel.getHeight()/2-j.getHeight()/2);
//then add Button into imageLabel
imageLabel.add(j);
Layout manager is usually recommended because it can fit different environment.

Swing Java Rotate JLabel but text be erased

I'm using swing Java to try to do something with java. Now I want to rotate JLabel and I did that. But unfortunelately, a part of my text in JLabel is erased (as in the image below). I have tried search but seem no one has problems as same as mine. I guess it's occured caused JLabels they overlaped.
and this is my code
serviceName[j] = new JLabel(name){
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
aT.rotate(Math.toRadians(300));
g2.setTransform(aT);
g2.setClip(oldshape);
super.paintComponent(g);
}
};
Can you give me the way to solved it
You should restore original transform and clip after your painting. Like this
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
g2.rotate(Math.toRadians(300));
super.paintComponent(g);
g2.setTransform(aT);
g2.setClip(oldshape);
}
Your JLabel subclass should also override getPreferredSize() to report the size it will be when it is rotated; otherwise the any layout manager that uses asks your component for its preferred size will use JLabel's version, which assumes the text is drawn horizontally.
Instead of attempting to rotate the component, another approach would be to create a Text Icon and add the Icon to a JLabel.
Once you have created the TextIcon you can then create a Rotated Icon to add to the label. The RotatedIcon will calculate the proper size of the Icon so therefore the size of the label will also be correct and no custom painting is required.
So the basic code would be something like:
JLabel label = new JLabel();
TextIcon textlIcon = new TextIcon(label, "Rotated Text");
label.setIcon( new RotatedIcon(textIcon, 300) );
Edit:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.border.*;
import javax.swing.table.*;
import java.io.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
OverlapLayout layout = new OverlapLayout(new Point(20, 0));
setLayout( layout );
addLabel("one");
addLabel("two");
addLabel("three or more");
addLabel("four");
}
private void addLabel(String text)
{
JLabel label = new JLabel();
TextIcon textIcon = new TextIcon(label, text);
label.setIcon( new RotatedIcon(textIcon, 300) );
label.setVerticalAlignment(JLabel.BOTTOM);
add(label);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
This example also uses the Overlap Layout so the labels can be painted over top of one another.
You may find some hints from this small program. Experiment on the values of setPrefferedSize to have more ideas. If you still can't solve the problem, please edit and add more codes in your question above.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import javax.swing.*;
public class InclinedLabels extends JFrame{
/** Creates a new instance of InclinedLabels */
public InclinedLabels() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JPanel jPanel1 = new JPanel();
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
add(jPanel1);
JPanel jPanel2 = new JPanel();
jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel2.setPreferredSize(new Dimension(10, 100));
add(jPanel2, BorderLayout.NORTH);
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel1.setPreferredSize(new java.awt.Dimension(200, 200));
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-400)/2, (screenSize.height-352)/2, 300, 352);
String str = "The quick brown fox jumps over the lazy dog";
String[] word = str.split(" ");
JLabel[] serviceName = new JLabel[str.length()];
String name;
for (int j=0; j<word.length; j++) {
name = word[j];
serviceName[j] = new JLabel(name){
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
aT.rotate(Math.toRadians(300));
g2.setTransform(aT);
g2.setClip(oldshape);
super.paintComponent(g);
}
};
serviceName[j].setPreferredSize(new Dimension(50,20));
serviceName[j].setBorder(BorderFactory.createLineBorder(Color.RED));
jPanel1.add(serviceName[j]);
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new InclinedLabels().setVisible(true);
}
});
}
}
Update:
I found a much closer hint that may solve this problem. The big factor here is the component layout. The null layout allows overlapping of JLabel components so it is the most appropriate layout to be used here. Then you have to customize the location and size of the labels through the setBounds method. In the code below there is serviceName[j].setBounds(xOffset + j*20,180, 170, 15); So in every loop iteration, the x location of the label is increased by 20. The size of all labels is 170 by 15. I also placed temporary borders to the components to help in understanding the output.
import java.awt.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;
public class InclinedLabels extends JFrame{
/** Creates a new instance of InclinedLabels */
public InclinedLabels() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-360)/2, (screenSize.height-352)/2, 360, 352);
JPanel jPanel1 = new JPanel();
jPanel1.setBorder(BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel1.setLayout(null); // null layout allows overlapping of components
add(jPanel1);
JPanel jPanel2 = new JPanel();
jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel2.setPreferredSize(new Dimension(10, 100));
add(jPanel2, BorderLayout.NORTH);
String str = "The quick brown fox jumpsssssssssssss123456 over the lazy dogssssssssssssss123456";
String[] word = str.split(" ");
JLabel[] serviceName = new JLabel[str.length()];
String name;
int xOffset = 30;
for (int j=0; j<word.length; j++) {
name = word[j];
serviceName[j] = new JLabel(name){
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
aT.rotate(Math.toRadians(300));
g2.setTransform(aT);
g2.setClip(oldshape);
super.paintComponent(g2);
}
};
serviceName[j].setBounds(xOffset + j*20,180, 170, 15); // experiment here
serviceName[j].setBorder(BorderFactory.createLineBorder(Color.RED));
jPanel1.add(serviceName[j]);
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new InclinedLabels().setVisible(true);
}
});
}
}
The limitation that I found in the code above is the width of the parent panel. In the example, the label having the text dogssssssssssssss123456 was not printed in whole. This can be overcome by increasing the width of the frame which in turn increases the width of jPanel1.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
public class Test {
public static void main(String[] args) {
// Create the first label, which will be rotated later.
Test.RotateLabel one = new Test.RotateLabel( "Rotated", 100, 100 );
one.setRotation( 270 );
JLayeredPane pane = new JLayeredPane();
pane.setLayer( one, JLayeredPane.DEFAULT_LAYER );
pane.add( one );
pane.setBorder(new javax.swing.border.LineBorder(Color.BLACK,1));
// Put the container pane in a frame and show the frame.
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( pane );
frame.setSize( 500, 500 );
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
static class RotateLabel extends JLabel {
private static final long serialVersionUID = 1L;
private int angle = 0;
public RotateLabel( String text, int x, int y ) {
super( text );
setBorder( new javax.swing.border.CompoundBorder(
new javax.swing.border.LineBorder( Color.red, 1), getBorder() ) );
int width = getPreferredSize().width;
int height = getPreferredSize().height;
setBounds(x, y, width, height);
}
#Override
public void paintComponent( Graphics g ) {
Graphics2D gx = (Graphics2D) g;
Shape old = gx.getClip();
gx.rotate(-Math.toRadians(45), getWidth() / 2, getHeight() / 2);
gx.setClip(old);
super.paintComponent(gx);
}
public void setRotation( int angle ) { this.angle = angle; }
}

Using JScrollBar to update Components

public class FaceMain extends JFrame {
CreateFace p1 = new CreateFace();
private ControlPanel panel;
public FaceMain(ControlPanel value) {
panel = value;
JFrame main = new JFrame();
main.setTitle("Face Frame");
main.setSize(new Dimension(600, 600));
main.setLocationRelativeTo(null);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setVisible(true);
Container c = main.getContentPane();
main.add(p1);
panel.eyesSetE(true);
JFrame control = new JFrame();
control.setTitle("Control Panel");
control.setSize(new Dimension(300, 300));
control.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
control.setLocationRelativeTo(main);
control.setVisible(true);
ControlPanel p2 = new ControlPanel(p1);
control.add(p2);
}
}
public class ControlPanel extends JPanel {
boolean eyesSetEdit = false, faceSetEdit = false, mouthSetEdit = false,
editEyes;
private Color purple = new Color(133, 22, 145);
private CreateFace face;
private CreateFace p1;
public ControlPanel(CreateFace value) {
face = value;
p1 = value;
setLayout(new GridLayout(4, 0));
JButton change = new JButton("Click");
add(change);
JLabel info = new JLabel("Click Above To Change Features",
JLabel.CENTER);
add(info);
JLabel info1 = new JLabel("Slide Below To Change Size", JLabel.CENTER);
add(info1);
JScrollBar slider = new JScrollBar(Scrollbar.HORIZONTAL, 0, 100, 0, 300);
add(slider);
public void eyesSetE(boolean x) {
eyesSetEdit = x;
}
public boolean getEyesSet() {
return eyesSetEdit;
}
I have expanded my class to try and change a boolean value which will be used exstensivly in the ControlPanel class to make decisions however everytime I start the program I get a nullpointerexception at the line "panel.eyesSetE(true);" Even if I try and call getEyesSet() I still recieve a nullpointer
You never change the instance of circle within the CreateCircle class, so it never changes size.
Don't use static for what should be an instance variable, instead make use of the instance of the class you created and provide a setter method to change the variable...
Basically, this example passes the instance of p1 to the ControlPanel pane so that it has some context by which to manipulate what you have previously created.
import datetest.CircleShort.ControlPanel;
import datetest.CircleShort.CreateCircle;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Scrollbar;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollBar;
public class CircleShort extends JFrame {
CreateCircle p1 = new CreateCircle();
public CircleShort() {
CreateCircle p1 = new CreateCircle();
JFrame main = new JFrame();
main.setSize(new Dimension(600, 600));
main.setLocationRelativeTo(null);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setVisible(true);
Container c = main.getContentPane();
main.add(p1);
JFrame control = new JFrame();
control.setTitle("Control Panel");
control.setSize(new Dimension(300, 300));
control.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
control.setLocationRelativeTo(main);
control.setVisible(true);
ControlPanel p2 = new ControlPanel(p1);
control.add(p2);
}
static class CreateCircle extends JComponent {
int circleX = 100;
Ellipse2D.Double circle;
public CreateCircle() {
circle = new Ellipse2D.Double(circleX, 50, 400, 350);
}
public void setCircleX(int x) {
circleX = x;
circle = new Ellipse2D.Double(circleX, 50, 400, 350);
repaint();
}
public int getCircleX() {
return circleX;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.red);
g2.fill(circle);
}
}
class ControlPanel extends JComponent {
private CreateCircle circle;
public ControlPanel(CreateCircle value) {
circle = value;
setLayout(new GridLayout(4, 0));
JButton change = new JButton("Click");
add(change);
JLabel info = new JLabel("Click Above To Change Color",
JLabel.CENTER);
add(info);
JLabel info1 = new JLabel("Slide Below To Change Size",
JLabel.CENTER);
add(info1);
JScrollBar slider = new JScrollBar(Scrollbar.HORIZONTAL, 0, 100, 0,
300);
add(slider);
slider.addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
System.out.println(e.getValue());
circle.setCircleX((circle.getCircleX() + (e.getValue() % 5)));
}
});
}
}
static class CircleRun {
public static void main(String[] args) {
new CircleShort();
}
}
}
static is evil until you truly understand how to use it. If you find yourself making some field or method static just because you can't seem to figure out how to access it, then you are likely doing something wrong, be careful with it...
The next question this actually raises is, "why?"
A JSlider would be a more appropriate control to use and would be conceptually easier for a user to understand

Categories