Установка фона JTextPane приводит к визуальным артефактам (Java) - PullRequest
0 голосов
/ 17 января 2020

это мой первый вопрос по stackoverflow, так что, пожалуйста, не будьте так трудны со мной (и моим Engli sh), я постараюсь сделать все возможное, чтобы задать хороший вопрос.

The проблема в , что предлагает заголовок -> установка фона JTextpane (в частности, установка его прозрачным). Поскольку метод setBackground принимает цветовой аргумент, путь, по которому я пошел, был с альфа-значением = 0. Это приводит к следующим визуальным артефактам:

пример изображения визуальных артефактов при выполнении кода ниже

enter image description here

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

У меня есть JFrame (myFrame), содержащий JPanel (Test ()), в которой я рисую. Фон этого JPanel установлен зеленым, как вы можете видеть в коде. Я сделал это, чтобы отличить фон TextPane от фактического фона панели.

У нас также есть поле ввода JTextPane ->, которое принимает пользовательский ввод (отображает то, что вы пишете). Это удерживается панелью прокрутки JScrollPane.

Таким образом, цель (что означает то, чего я пытаюсь достичь): - это поле ввода пользователя, которое является прозрачным, но по-прежнему отображает текст, который помещает пользователь в. Я пытался добиться этого, установив фон поля ввода и полосы прокрутки в прозрачный цвет.

Я был бы очень признателен, если вы просто не наберете что-то вроде (вам нужно setOpague (false ) для ....) если вы не знаете точно, о чем говорите, потому что я почти перепробовал все, что мог придумать, и прочитал каждый пост, который смог найти в inte rnet о проблеме. Я опубликую некоторые из них в конце. Итак ...

Что я уже пробовал:

Обычный способ, который я нашел при поиске чего-то вроде "Как сделать TextPane прозрачным", заключался в setOpague (false) на себя так же как область прокрутки и область просмотра области прокрутки. 1. Читая о том, что метод на самом деле делает, я не думаю, что это правильное решение. 2. установка Opague (false) на эти три приводит к тому, что все невидимо, так что это не хорошо. Снова упаковываем кадр после установки фона. Либо ничего не было исправлено, либо компоненты стали полностью невидимыми.

Я также попробовал: setBackground (null), установив фон только для поля ввода (только для каждого компонента и каждой возможной комбинации из трех (scrollpane, viewport, inputfield)), смешивая setOpague (true) / setOpague (false) / setBackground (...) всеми возможными способами. Переопределение метода paintComponent для текстовой панели и полосы прокрутки показалось мне хорошим подходом, но я не слишком далеко продвинулся в этом.

Итак, вот код :

public class Test extends JPanel {

    JTextPane inputField = new JTextPane();
    JScrollPane scrollpane = new JScrollPane(inputField);

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        inputField.setBounds(10,10,100,100);
        scrollpane.setBounds(10,10,100,100);
    }

    public Test(){

        this.setOpaque(true);
        this.setBackground(Color.GREEN);

        inputField.setBounds(10,10,100,100);
        scrollpane.setBounds(10,10,100,100);

        inputField.setBackground(new Color(0,0,0,0));
        scrollpane.setBackground(new Color(0,0,0,0));
        scrollpane.getViewport().setBackground(new Color(0,0,0,0));
        this.add(scrollpane);

    }

    public static void main(String[] args) {
        JFrame myFrame = new JFrame();
        myFrame.add(new Test());
        myFrame.pack();
        myFrame.setSize(640,480);
        myFrame.setPreferredSize(new Dimension(640,480));
        myFrame.setVisible(true);
    }
}

А вот некоторые ссылки на прочитанные мной сообщения, в которых описываются похожие проблемы:

Java - Transparent JScrollPane

Transparent JEditorPane в JScrollPane над фоном JPanel

setOpaque (true / false); Java

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

Ответы [ 2 ]

1 голос
/ 17 января 2020

Не используйте прозрачный цвет в качестве фона - его сложно удалить (например, когда компонент перекрашивается (и непрозрачен)).

Не использовать setBounds (если не используется ноль LayoutManager ). В приведенном ниже примере я использовал setPreferredSize, но все же лучше правильно использовать LayoutManager (я немного ленив, и сейчас много работы).

public class Test extends JPanel {

    JTextPane inputField = new JTextPane();
    JScrollPane scrollpane = new JScrollPane(inputField);

    public Test(){

        this.setOpaque(true);
        this.setBackground(Color.GREEN);

        inputField.setPreferredSize(new Dimension(300, 100));

        inputField.setOpaque(false);
        scrollpane.setOpaque(false);
        scrollpane.getViewport().setOpaque(false);

        this.add(scrollpane);

    }

    public static void main(String[] args) {
        JFrame myFrame = new JFrame();
        myFrame.add(new Test());
        myFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        myFrame.setPreferredSize(new Dimension(640,480));
        myFrame.pack();
        myFrame.setVisible(true);
    }
}

Весь код main должен вызываться в EDT (например, SwingUtilities.invokeLater), поскольку он манипулирует компонентами колебания, но это не является частью вопроса (и не относится к ) здесь, поскольку setVisible - последняя команда - компоненты не отображаются во время изменения).

0 голосов
/ 17 января 2020

Ваша программа иногда выдает мне ошибки при запуске. Обязательно запустите свинг GUI из EDT (invokeLater()).

Строка, которая вызывает вашу проблему:

scrollpane.getViewport().setBackground(new Color(0,0,0,0));

Также - есть ли какая-то причина, по которой вы устанавливать границы вручную вместо использования менеджера компоновки?

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

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;

public class Test extends JPanel {

    JTextPane inputField = new JTextPane();
    JScrollPane scrollpane = new JScrollPane(inputField);

    public Test(){
        this.setBackground(Color.GREEN);

        scrollpane.setPreferredSize(new Dimension(300, 300));

        inputField.setBackground(Color.GREEN);

        this.add(scrollpane);

    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                   JFrame myFrame = new JFrame();
                    myFrame.add(new Test());
                    myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    myFrame.setPreferredSize(new Dimension(640,480));
                    myFrame.pack();
                    myFrame.setVisible(true);
            }
        });
    }
}
...