So, I am creating a new Canvas (JPanel) class: Canvas canvas = new Canvas(); and then I am calling a method on that class: canvas.addTextBox();
Now, from within this Canvas class, I want to add a new jTextArea to the Canvas. I tried using the code below but it isn't showing up. Not sure what I am doing wrong. Thanks!
class Canvas extends JPanel {
public Canvas() {
this.setOpaque(true);
//this.setBackground(Color.WHITE);
}
public void addTextBox() {
final JTextArea commentTextArea = new JTextArea(10, 10);
commentTextArea.setLineWrap(true);
commentTextArea.setLineWrap(true);
commentTextArea.setWrapStyleWord(true);
commentTextArea.setVisible(true);
}
}
Full Code
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class UMLEditor {
public static void main(String[] args) {
JFrame frame = new UMLWindow();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(30, 30, 1000, 700);
frame.getContentPane().setBackground(Color.white);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class UMLWindow extends JFrame {
Canvas canvas = new Canvas();
private static final long serialVersionUID = 1L;
public UMLWindow() {
addMenus();
}
public void addMenus() {
getContentPane().add(canvas);
JMenuBar menubar = new JMenuBar();
JMenuItem newTextBox = new JMenuItem("New Text Box");
newTextBox.setMnemonic(KeyEvent.VK_E);
newTextBox.setToolTipText("Exit application");
newTextBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
canvas.addTextBox();
}
});
menubar.add(newTextBox);
setJMenuBar(menubar);
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
class Canvas extends JPanel {
public Canvas() {
this.setOpaque(true);
//this.setBackground(Color.WHITE);
}
public void addTextBox() {
final JTextArea commentTextArea = new JTextArea(10, 10);
commentTextArea.setLineWrap(true);
commentTextArea.setLineWrap(true);
commentTextArea.setWrapStyleWord(true);
commentTextArea.setVisible(true);
}
}
The addTextBox method only creates a JTextArea. It never adds it to the JPanel
You will need to add the following line to addTextBox method:
add( commentTextArea );
In case the JFrame which contains your components is already visible on screen when the addTextBox method is called, you need to invalidate the container as well. Simply add
revalidate();
repaint();
Related
I am writing in a notepad. And I want to implement text scaling in my notepad. But I don't know how to do it. I'm trying to find it but everyone is suggesting to change the font size. But I need another solution.
I am create new project and add buttons and JTextArea.
package zoomtest;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JTextArea;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class zoom {
private JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
zoom window = new zoom();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public zoom() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.NORTH);
JButton ZoomIn = new JButton("Zoom in");
ZoomIn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//Code here...
}
});
panel.add(ZoomIn);
JButton Zoomout = new JButton("Zoom out");
Zoomout.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//Code here...
}
});
panel.add(Zoomout);
JTextArea jta = new JTextArea();
frame.getContentPane().add(jta, BorderLayout.CENTER);
}
}
Introduction
Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay close attention to the Laying Out Components Within a Container section.
I reworked your GUI. Here's how it looks when the application starts. I typed some text so you can see the font change.
Here's how it looks after we zoom out.
Here's how it looks after we zoom in.
Stack Overflow scales the images, so it's not as obvious that the text is zooming.
Explanation
Swing was designed to be used with layout managers. I created two JPanels, one for the JButtons and one for the JTextArea. I put the JTextArea in a JScrollPane so you could type more than 10 lines.
I keep track of the font size in an int field. This is a simple application model. Your Swing application should always have an application model made up of one or more plain Java getter/setter classes.
Code
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ZoomTextExample {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
new ZoomTextExample();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private int pointSize;
private Font textFont;
private JFrame frame;
private JTextArea jta;
private JTextField pointSizeField;
public ZoomTextExample() {
this.pointSize = 16;
this.textFont = new Font(Font.DIALOG, Font.PLAIN, pointSize);
initialize();
}
private void initialize() {
frame = new JFrame("Text Editor");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createButtonPanel(), BorderLayout.NORTH);
frame.add(createTextAreaPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
JButton zoomIn = new JButton("Zoom in");
zoomIn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
incrementPointSize(+2);
updatePanels();
}
});
panel.add(zoomIn);
panel.add(Box.createHorizontalStrut(20));
JLabel label = new JLabel("Current font size:");
panel.add(label);
pointSizeField = new JTextField(3);
pointSizeField.setEditable(false);
pointSizeField.setText(Integer.toString(pointSize));
panel.add(pointSizeField);
panel.add(Box.createHorizontalStrut(20));
JButton zoomOut = new JButton("Zoom out");
zoomOut.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
incrementPointSize(-2);
updatePanels();
}
});
panel.add(zoomOut);
return panel;
}
private JPanel createTextAreaPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
jta = new JTextArea(10, 40);
jta.setFont(textFont);
JScrollPane scrollPane = new JScrollPane(jta);
panel.add(scrollPane, BorderLayout.CENTER);
return panel;
}
private void updatePanels() {
pointSizeField.setText(Integer.toString(pointSize));
textFont = textFont.deriveFont((float) pointSize);
jta.setFont(textFont);
frame.pack();
}
private void incrementPointSize(int increment) {
pointSize += increment;
}
}
I am using a JDialog for a project, which is load when I click on a button located inside a JFrame.
This JDialog is supposed to display an image, but the image appears only when the code called by the JFrame class is executed. My problem is that I want the image to be displayed when I call it, not at the end of my programm.
Here is my code of the JDialog :
public class LoadingWindow {
private JDialog dialog;
public LoadingWindow() {
this.dialog = new JDialog();
this.dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
this.dialog.setTitle("Veuillez patienter");
this.dialog.setSize(300, 200);
URL url = LoadingWindow.class.getResource("/images/wait.gif");
ImageIcon icon = new ImageIcon(url);
JLabel imageLabel = new JLabel();
imageLabel.setIcon(icon);
imageLabel.setHorizontalAlignment(JLabel.CENTER);
imageLabel.setVerticalAlignment(JLabel.CENTER);
this.dialog.getContentPane().add(imageLabel);
this.dialog.setLocationRelativeTo(null);
this.dialog.setVisible(true);
}
public void stop() {
this.dialog.dispose();
}
}
Inside my JFrame, I call the JDialog this way :
MyJDialog mjd = new MyJDialog ();
[CODE]
mjd.stop();
Thanks !
Here's an example of a GUI that opens a JDialog.
Here's the image I used.
I create a JFrame and a JPanel with a JButton. The JButton has an ActionListener that opens a JDialog. The JDialog displays the car image.
Here's the complete runnable code I used.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class JDialogTest implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new JDialogTest());
}
private JFrame frame;
#Override
public void run() {
frame = new JFrame("JDialog Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(
150, 100, 150, 100));
panel.setPreferredSize(new Dimension(400, 400));
JButton button = new JButton("Open JDialog");
button.addActionListener(new ButtonListener());
panel.add(button);
return panel;
}
public class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
new CalculateDecor(frame, "Spash Screen");
}
}
public class CalculateDecor extends JDialog {
private static final long serialVersionUID = 1L;
public CalculateDecor(JFrame frame, String title) {
super(frame, true);
Image image = getImage();
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setTitle(title);
JPanel panel = new JPanel(new BorderLayout());
JLabel label = new JLabel();
label.setHorizontalAlignment(JLabel.CENTER);
label.setIcon(new ImageIcon(image));
panel.add(label);
add(panel);
pack();
setLocationRelativeTo(frame);
setVisible(true);
System.out.println(getDecorationSize());
}
private Dimension getDecorationSize() {
Rectangle window = getBounds();
Rectangle content = getContentPane().getBounds();
int width = window.width - content.width;
int height = window.height - content.height;
return new Dimension(width, height);
}
private Image getImage() {
try {
return ImageIO.read(getClass().getResourceAsStream(
"/car.jpg"));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
}
In my code, currently each card is the size of my frame. How do I set different sizes of each of my panels in the layout. I tried making the frame different sizes by calling the run() method and changing the size of the frame, but it does not work. I'm hoping there is another way.
This is my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class GameManager
{
JFrame frame;
JPanel cards,Title;
public GameManager()
{
cards = new JPanel(new CardLayout());
Title title = new Title();
cards.add(title,"title");
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, "title");
}
public static void main(String [] args)
{
GameManager gm = new GameManager();
gm.run();
}
public void run()
{
frame = new JFrame("Greek Olympics");
frame.setSize(1000,1000);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(cards);
frame.setVisible(true);
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, "title");
}
public class Title extends JPanel
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.fillRect(100,100,100,100);
}
}
}
How would I change the code so that if I wanted to add another panel with a different size?
How do I set different sizes of each of my panels in the layout
First, understand that CardLayout will use the preferredSize property of all the view's it's managing to determine the best resulting size that the container it's managing should use. This means that if you call pack on the frame (instead of setSize), it will be sized (automatically) to the largest component been managed (by the CardLayout)
How would I change the code so that if I wanted to add another panel with a different size?
Each component you add to the CardLayout should either be calculating it's size through one or more appropriate layout managers, or, in the case of custom components, be providing a sizing hint through the getPreferredSize method
public class Title extends JPanel
{
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.fillRect(100,100,100,100);
}
}
Then, instead of using setSize, use pack
public void run()
{
frame = new JFrame("Greek Olympics");
//frame.setSize(1000,1000);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(cards);
frame.pack();
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, "title");
frame.setVisible(true);
}
Example...
This is a basic example which sets up two panels, one with preferredSize of 200x200 and one with 400x400
When you run it, you will find the window will be at least 400x400 and both panels will be the same size
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CardLayout cardLayout = new CardLayout();
JPanel base = new JPanel(cardLayout);
base.add(makePanel(200, 200, Color.RED), "red");
base.add(makePanel(400, 400, Color.BLUE), "blue");
frame.add(base);
JButton blue = new JButton("Blue");
blue.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(base, "blue");
}
});
JButton red = new JButton("red");
red.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(base, "red");
}
});
JPanel buttons = new JPanel();
buttons.add(red);
buttons.add(blue);
frame.add(buttons, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public TestPane makePanel(int width, int height, Color background) {
TestPane pane = new TestPane(new Dimension(width, height));
pane.setBackground(background);
return pane;
}
public class TestPane extends JPanel {
private JLabel label;
private Dimension preferredSize;
public TestPane(Dimension size) {
label = new JLabel("...");
setLayout(new GridBagLayout());
add(label);
this.preferredSize = size;
}
#Override
public Dimension getPreferredSize() {
return preferredSize;
}
#Override
public void invalidate() {
super.invalidate();
label.setText(getWidth() + "x" + getHeight());
}
}
}
It is said in manual, that if child does not implement Scrollable, then JScrollPane rely on preferredSize properties of it's content.
Apparently this is not true for me. I am increasing preferred height, but JScrollPane does not feel or react on it.
package tests;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Try01_JScrollPane extends JFrame {
private static final long serialVersionUID = 4123186105171813186L;
private static final Logger log = LoggerFactory.getLogger(Try01_JScrollPane.class);
JPanel yellowPanel = new JPanel();
{
yellowPanel.setPreferredSize(new Dimension(200,50));
yellowPanel.setSize(new Dimension(200,50));
yellowPanel.setBackground(Color.yellow);
}
JScrollPane scrollPane = new JScrollPane(yellowPanel);
{
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
}
AbstractAction increaseAction = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
yellowPanel.setPreferredSize(new Dimension(yellowPanel.getPreferredSize().width, yellowPanel.getPreferredSize().height+100));
log.debug("preferred height is now {}", yellowPanel.getPreferredSize().height);
}
};
Timer increaseTimer = new Timer(1000, increaseAction);
{
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(200, 400);
setTitle("Try01_JScrollPane");
increaseTimer.start();
setVisible(true);
}
public static void main(String[] args) {
new Try01_JScrollPane();
}
}
JPanel is container and JComponent too, for any changes to JViewport you have to notify the JScrollPane:-)
.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Try01_JScrollPane extends JFrame {
private static final long serialVersionUID = 4123186105171813186L;
private JFrame frame = new JFrame("Try01_JScrollPane");
private JPanel yellowPanel = new JPanel();
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
{
yellowPanel.setBackground(Color.yellow);
}
private JScrollPane scrollPane = new JScrollPane(yellowPanel);
{
scrollPane.setPreferredSize(new Dimension(400, 300));
}
private AbstractAction increaseAction = new AbstractAction() {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
yellowPanel.setPreferredSize(
new Dimension(yellowPanel.getPreferredSize().width + 100,
yellowPanel.getPreferredSize().height + 100));
yellowPanel.revalidate();
yellowPanel.repaint();
}
};
private Timer increaseTimer = new Timer(1000, increaseAction);
public Try01_JScrollPane() {
frame.add(scrollPane, BorderLayout.CENTER);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocation(150, 150);
frame.setVisible(true);
increaseTimer.start();
increaseTimer.setRepeats(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Try01_JScrollPane();
}
});
}
}
The JScrollPane cuts a view port out of a backing content have a scroll pane layout. The part on getPreferredSize refers to this layout. It simply says that the JScrollPane / view port rectangle is not influenced by the backing content and vice versa: content is layed out with respect to their preferred size.
So a change of preferred size need a new layouting. More sence would be to:
initialize with a setPreferredSize.
afterwards call setSize to resize.
I have written a small test program which creates a split pane in which one of the pane's is a text area. I have added a meubar and menuitems to the pane but i donot see them in the gui that is created.
Could anyone pls point out what the wrong thing did i do over here in the below program:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.JMenuBar;
import java.util.*;
import javax.swing.text.BadLocationException;
import java.awt.*;
import java.io.IOException;
//SplitPaneDemo itself is not a visible component.
public class SplitPaneDemo extends JFrame
implements ActionListener {
private JTextArea ta;
private JMenuBar menuB;
private JMenu dbM;
private JMenuItem cnadb,bsmdb,cdmdb;
private JLabel picture;
private JSplitPane splitPane;
public SplitPaneDemo() {
ta = new JTextArea(); //textarea
ta.setLineWrap(true);
ta.setWrapStyleWord(true);
ta.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent ke )
{
int code = ke.getKeyCode();
int modifiers = ke.getModifiers();
if(code == KeyEvent.VK_ENTER && modifiers == KeyEvent.CTRL_MASK)
{
System.out.println("cmd in table:");
}
}
});
JScrollPane taPane = new JScrollPane(ta);
picture = new JLabel();
picture.setFont(picture.getFont().deriveFont(Font.ITALIC));
picture.setHorizontalAlignment(JLabel.CENTER);
JScrollPane pictureScrollPane = new JScrollPane(picture);
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
taPane, pictureScrollPane);
splitPane.setOneTouchExpandable(true);
splitPane.setDividerLocation(450);
//Provide minimum sizes for the two components in the split pane.
Dimension minimumSize = new Dimension(100, 100);
taPane.setMinimumSize(minimumSize);
pictureScrollPane.setMinimumSize(minimumSize);
//Provide a preferred size for the split pane.
splitPane.setPreferredSize(new Dimension(900, 900));
menuB = new JMenuBar(); //menubar
dbM = new JMenu("DB"); //file menu
cnadb = new JMenuItem("CNA");
bsmdb = new JMenuItem("BSM");
cdmdb = new JMenuItem("CDM");
setJMenuBar(menuB);
menuB.add(dbM);
dbM.add(cnadb);
dbM.add(bsmdb);
dbM.add(cdmdb);
cnadb.addActionListener(this);
bsmdb.addActionListener(this);
cdmdb.addActionListener(this);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
}
public void valueChanged(ListSelectionEvent e) {
}
public JSplitPane getSplitPane() {
return splitPane;
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("SplitPaneDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SplitPaneDemo splitPaneDemo = new SplitPaneDemo();
frame.getContentPane().add(splitPaneDemo.getSplitPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
You add the JMenuBar in your SplitPaneDemo class, but when you actually call createAndShowGUI, you make a new JFrame and only add the SplitPane to it with the call to getSplitPane. This new frame has no knowledge of the menu bar.
If you are extending JFrame in SplitPaneDemo, why not use that to make the frame for your gui?