Moin, Leute!
Ich möchte eine JTextPane mit Farbverlauf als Hintergrund haben. Dafür habe ich die Tipps hier befolgt.
Die JTextPane soll sich in einem JScrollPane befinden. Da bekam ich nun das Problem, dass die GradientPaint immer weiter in die Länge gezogen wurde, je mehr Zeilen der Text bekam. Sie soll jedoch "statisch" an einer Stelle bleiben, nämlich vom Anfang bis zum Ende des sichtbaren Bereichs des JTextPane gehen. Daher zeichne ich anhand des sichtbaren Bereichs des JTextPane neu.
Dafür nun folgender lauffähiger Code:
Ändere ich die Größe des JFrame, so wird der Farbverlauf auch ordentlich neugezeichnet. Wird jedoch die ScrollBar bewegt, hinterlässt dies "Schlieren", obwohl die JTextPane komplett neugezeichnet wird. Die in der Konsole stehenden Maße des sichtbaren Bereichs sehen ebenfalls korrekt aus.
Wo liegt der Fehler?
Ich möchte eine JTextPane mit Farbverlauf als Hintergrund haben. Dafür habe ich die Tipps hier befolgt.
Die JTextPane soll sich in einem JScrollPane befinden. Da bekam ich nun das Problem, dass die GradientPaint immer weiter in die Länge gezogen wurde, je mehr Zeilen der Text bekam. Sie soll jedoch "statisch" an einer Stelle bleiben, nämlich vom Anfang bis zum Ende des sichtbaren Bereichs des JTextPane gehen. Daher zeichne ich anhand des sichtbaren Bereichs des JTextPane neu.
Dafür nun folgender lauffähiger Code:
Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
public class GradientTextPane extends JTextPane {
@Override
protected void paintComponent(Graphics g) {
final boolean opaque = isOpaque();
if (opaque) {
final Graphics2D g2d = (Graphics2D) g.create();
final Rectangle size = getVisibleRect();
final int x1 = size.x;
final int y1 = size.y;
final int x2 = size.width + x1;
final int y2 = size.height + y1;
final GradientPaint gp = new GradientPaint(0, y1, Color.WHITE, 0, y2, Color.BLACK);
System.out.println(x1 + "\t" + y1 + "\t" + x2 + "\t" + y2);
g2d.setPaint(gp);
g2d.fillRect(x1, y1, x2, y2);
// Debugging: Rotes X kennzeichnet sichtbaren Bereich
g2d.setColor(Color.RED);
g2d.drawLine(x1, y1, x2, y2);
g2d.drawLine(x2, y1, x1, y2);
g2d.dispose();
setOpaque(false);
}
super.paintComponent(g);
setOpaque(opaque);
}
public static void main(String[] args) {
final JPanel contentPane = new JPanel(new BorderLayout());
final GradientTextPane textPane = new GradientTextPane();
textPane.setEditable(false);
final JScrollPane scrollPane = new JScrollPane(textPane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
contentPane.add(scrollPane, BorderLayout.CENTER);
final JTextField textField = new JTextField();
textField.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final String message = textField.getText().trim();
if (!message.isEmpty()) {
final Document document = textPane.getDocument();
try {
document.insertString(document.getLength(), message + System.getProperty("line.separator"), null);
textField.setText("");
} catch (BadLocationException e1) {
e1.printStackTrace();
JOptionPane.showMessageDialog(contentPane, e1.getStackTrace(), e1.toString(), JOptionPane.ERROR_MESSAGE);
}
}
}
});
contentPane.add(textField, BorderLayout.SOUTH);
final JFrame frame = new JFrame("GradientTextPane");
frame.setContentPane(contentPane);
frame.setSize(250, 150);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
textField.requestFocusInWindow();
}
}
Wo liegt der Fehler?