Позволяя пользователям "рисовать" и изменять размер JTextArea

Я хочу, чтобы пользователи могли "рисовать" с помощью мыши (щелкать и перетаскивать), чтобы создать и изменить размер JTextArea. Кроме того, я хотел бы, чтобы текстовые области были изменяемого размера.

Что-то вроде этого:

введите описание изображения здесь

приходит на ум, но как JTextArea, а не просто квадрат.

Есть ли что-то в Java, что позволило бы мне легко это сделать? Сначала я подумал о том, чтобы позволить пользователю нарисовать прямоугольник и просто взять координаты и размер, чтобы создать JTextArea. Я не уверен, как сделать изменение размера, хотя.

Изменить: "Компонент Resizer / Reszing" был термин, который я искал, и я добавляю его здесь на случай, если кто-то ищет что-то подобное!

4 ответа

Вы можете найти решение здесь, я уже попробовал его, и результат очень хороший. В руководстве есть ссылка на другую реализацию здесь.

Вы должны быть в состоянии использовать компонент Resizer.

Изменение размера JTextArea может быть достаточно легко выполнено с помощью вызова setBounds(...) для него - или лучше для JScrollPane, который его содержит, но вам нужно будет использовать нулевую или аналогичную (JLayeredPane) компоновку для контейнера, который содержит JTextArea и, вероятно, потребуется перекрасить контейнер после изменения размера JScrollPane. Вам также нужно будет повторно проверить область просмотра области прокрутки, чтобы она изменила расположение текстовой области, которую она содержит.

например,

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

@SuppressWarnings("serial")
public class ResizeableTextArea extends JPanel {
   private static final int PREF_WIDTH = 700;
   private static final int PREF_HEIGHT = 500;
   private static final int ROWS = 60;
   private static final int COLS = 80;
   private static final Color RECT_COLOR = new Color(180, 180, 255);

   private JTextArea textArea = new JTextArea(ROWS, COLS);
   private JScrollPane scrollPane = new JScrollPane(textArea);
   private int x, y, width, height;
   private boolean drawRect = false;

   public ResizeableTextArea() {
      setLayout(null);
      add(scrollPane);

      MyMouseAdapter myMouseAdapter = new MyMouseAdapter(); 
      addMouseListener(myMouseAdapter);
      addMouseMotionListener(myMouseAdapter);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (drawRect) {
         g.setColor(RECT_COLOR);
         g.drawRect(x, y, width, height);         
      }
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_WIDTH, PREF_HEIGHT);
   }

   private class MyMouseAdapter extends MouseAdapter {
      private int innerX, innerY;

      @Override
      public void mousePressed(MouseEvent e) {
         x = e.getX();
         y = e.getY();
         innerX = x;
         innerY = y;
         width = 0;
         height = 0;
         drawRect = true;
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         calcBounds(e);

         drawRect = true;
         ResizeableTextArea.this.repaint();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         calcBounds(e);

         drawRect = false;
         scrollPane.setBounds(x, y, width, height);
         scrollPane.getViewport().revalidate();
         ResizeableTextArea.this.repaint();

      }

      private void calcBounds(MouseEvent e) {
         width = Math.abs(innerX - e.getX());
         height = Math.abs(innerY - e.getY());
         x = Math.min(innerX, e.getX());
         y = Math.min(innerY, e.getY());
      }

   }

   private static void createAndShowUI() {
      JFrame frame = new JFrame("ResizeableTextArea");
      frame.getContentPane().add(new ResizeableTextArea());
      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();
         }
      });
   }
}

Это не очень хорошая идея, конечно, можно использовать Image или ImageIcon в качестве BackGround, лучше использовать для этого JLabel с Icon, тогда вы можете легко рисовать выделение

Другие вопросы по тегам