0

So, on the click of a JMenu button, I want to dynamically add a JTextArea to my JPanel. For some reason, it isn't showing up when it is expected to. I am using this code to add it:

drag = new DragListener();
JTextArea textArea = new JTextArea("Some text\nSome other text");
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
add(textArea);
textArea.addMouseListener(drag);
textArea.addMouseMotionListener(drag);

And I know this code works when I do it when the JPanel class is initialized, like this:

public MyPanel() {
    drag = new DragListener();
    JTextArea textArea = new JTextArea("Some text\nSome other text");
    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true);
    add(textArea);
    textArea.addMouseListener(drag);
    textArea.addMouseMotionListener(drag);
}

But when I add it dynamically using another method, it isn't adding. Why is this

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.event.MouseInputAdapter;

public class Editor {

    public static void main(String[] args) {
        JFrame frame = new Window();
        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 Window extends JFrame {
    MyPanel myPanel = new MyPanel();

    private static final long serialVersionUID = 1L;

    public Window() {
        addMenus();
    }

    public void addMenus() {

        getContentPane().add(myPanel);

        JMenuBar menubar = new JMenuBar();

        JMenuItem addBox = new JMenuItem("Add Menu");
        addBox.setMnemonic(KeyEvent.VK_E);
        addBox.setToolTipText("Exit application");
        addBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                myPanel.addBox();
            }
        });

        menubar.add(addBox);
        setJMenuBar(menubar);

        setSize(300, 200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
}

class MyPanel extends JPanel {
    private static final long serialVersionUID = 1L;
    DragListener drag;

    public MyPanel() {
        drag = new DragListener();
        drag = new DragListener();
        JTextArea textArea = new JTextArea("Some text\nSome other text");
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        add(textArea);
        textArea.addMouseListener(drag);
        textArea.addMouseMotionListener(drag);
    }

    public void addBox() {
        drag = new DragListener();
        JTextArea textArea2 = new JTextArea("Some text\nSome other text");
        textArea2.setLineWrap(true);
        textArea2.setWrapStyleWord(true);
        add(textArea2);
        textArea2.addMouseListener(drag);
        textArea2.addMouseMotionListener(drag);
        repaint();
        revalidate();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
    }

    public class DragListener extends MouseInputAdapter {
        Point location;
        MouseEvent pressed;

        public void mousePressed(MouseEvent me) {
            pressed = me;
        }

        public void mouseDragged(MouseEvent me) {
            Component component = me.getComponent();
            location = component.getLocation(location);
            int x = location.x - pressed.getX() + me.getX();
            int y = location.y - pressed.getY() + me.getY();
            component.setLocation(x, y);
        }
    }

}

Update

Now that I have solved this problem, I have ran into another.

When I add a new JTextArea to the Panel, it is resetting all of the other JTextArea's positions on the panel. Ideas?

enter image description here

nick
  • 309
  • 1
  • 5
  • 15
  • 1
    *"on the click of a JMenu button, I want to dynamically add a JTextArea to my JPanel."* Use a `CardLayout` instead.. It is easy and it works. – Andrew Thompson Nov 02 '14 at 23:45

1 Answers1

3

Add...

revalidate();
repaint();

to the end of your addBox method, this will encourage the layout manager to update the container the repaint manager to repaint the component

Also, please don't use JMenuBar and JMenuItems this way, it is counter intuitive to users, instead, use a JToolBar and JButton

See How to Use Tool Bars for more details

Dragging the JTextArea in this manner is also...annoying. How does the user highlight the text now?

Take a look at Dragging-and-dropping to move a JTextArea around on JPanel for another idea

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Thanks. I tried using repaint() but I was unaware of using revalidate(). Also, will look into JToolBar! – nick Nov 02 '14 at 23:50
  • I have updated the question with yet another problem I've run into. Any help is appreciated. Thanks :) – nick Nov 03 '14 at 00:24
  • Does it have anything to do with revalidate() ? – nick Nov 03 '14 at 00:26
  • Actually, yes, the panel is under the control of a layout manager, calling `revalidate` will cause the layout manager to re-evaluate the position and size of the components under it's control – MadProgrammer Nov 03 '14 at 00:28
  • Anyway to fix this? Can you override revaildate by chance? The only way I can think is to keep track of each JTextArea's coordinates and then set them on revalidate. Not sure if there is an easier way, though – nick Nov 03 '14 at 00:31
  • Sorry, no experience with layout managers. I'll check them out. Will I need a layout manager for each JTextArea or one for the whole JPanel? – nick Nov 03 '14 at 00:34
  • 1
    For an [example](http://stackoverflow.com/questions/11819669/absolute-positioning-graphic-jpanel-inside-jframe-blocked-by-blank-sections/11822601#11822601). You will only need a single layout manager for the panel – MadProgrammer Nov 03 '14 at 00:37
  • Thanks, will check out your answer. – nick Nov 03 '14 at 00:38