Лучший выбор: TextLayout или JTextComponent для компонента "эллипс с редактируемым текстом"? - PullRequest
0 голосов
/ 16 июня 2011

Если вы когда-либо использовали Visio или редактор диаграмм классов UML, у вас есть представление о том, чего я пытаюсь достичь: в JFrame пользователи могут добавлять эллипсы, заключающие небольшое редактируемое текстовое поле.Эти эллипсы могут быть перемещены в кадре, когда пользователь их перетаскивает.При нажатии на эллипс текст становится редактируемым: появляется карат, возможно выделение подстроки и т. Д.

У меня настроена базовая структура: «эллипс» является автономным компонентом,с методами, вызванными на него из содержащего JFrame и его слушателей.Я попробовал два подхода:

  1. в методе draw () компонента, использовать TextLayout для нахождения границ, расположить содержащийся текст внутри эллипса и нарисовать его во фрейме, используя TextLayout'sрисовать().Это быстро.Перетаскивание компонентов в JFrame, поведение при наведении мыши и щелчке мыши - все просто.Однако для функциональности редактирования мне кажется, что мне нужно будет написать много пользовательского кода для обработки проверки попадания, позиционирования в каратах, выделения текста, переноса строк и т. Д.

  2. с компонентом, содержащимссылка на содержащий JFrame и добавление или изменение положения TextComponent в этом JFrame после рисования эллипса.Это имеет преимущество всего встроенного поведения TextComponent для редактирования и переноса строк.Но логистика на самом деле неаккуратная, и расположение TextComponent также становится беспорядочным, особенно когда пользователь перетаскивает компонент.

Возможно, я думаю, что все это неправильно.Кто-нибудь может предложить простой способ сделать это, что я еще не наткнулся?

1 Ответ

0 голосов
/ 16 июня 2011

Почему бы вам не совместить оба ваших подхода.Пока вы редактируете, отобразите текстовый компонент, в противном случае закрасьте весь текст, используя TextLayout.В следующем примере кода показан такой подход, расширяющий простое JComponent.Он рисует прямоугольную форму с текстом в нем, и если вы щелкнете внутри, это показывает возможность редактирования.Как только вы снова нажмете снаружи, компонент исчез.Обратите внимание, что в этом базовом примере отсутствуют все функции обработки редактирования.

class TestComponent extends JComponent {
    JTextArea jta = new JTextArea("12345");

    public TestComponent() {
        setPreferredSize(new Dimension(400, 400));
        setLayout(null);
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(final MouseEvent e) {
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        if (e.getX() >= 40 && e.getX() <= 200 && e.getY() >= 40 && e.getY() <= 80) {
                            TestComponent.this.add(jta);
                            jta.setBounds(42, 42, 156, 36);
                        } else {
                            TestComponent.this.remove(jta);
                        }
                        repaint();
                    }
                });
            }
        });
    }

    @Override
    public void paintComponent(Graphics _g) {
        Graphics2D g = (Graphics2D) _g;
        g.drawRect(40, 40, 160, 40);
        TextLayout layout = new TextLayout("12345", g.getFont(), g.getFontRenderContext());
        layout.draw(g, 42, 42 + layout.getAscent());
    }
}
...