2013-03-25 63 views
3

我很抱歉没有更好的标题,但我不知道如何进一步指定错误,因为我不了解它的性质。当问题被理解时,也许有人可以编辑它。JTextPane中的布局问题

我正在编写一个应用程序,用户可以在该应用程序中将图标添加到文本字段中。我显然选择了JTextPane来显示文字和图标。在玩了类的insertComponent()函数后,我遇到了一些奇怪的布局问题,所以我决定在oracle.com上查找教程。在查看示例的source code后,我决定采取相同的操作,并使用样式将组件添加到底层的StyledDocument。当我开始第一次测试时,当我发现时,布局问题保持不变。

那么,究竟发生了什么?

enter image description here

我想要的文本窗格中显示为“abcOdefO”,但你可以通过截图出来,这两个图标(圆圈)有一些空间给他们的权利。我希望该图标被视为稍大的字符,因此它只应占用尽可能多的空间,而不是(availableSpace/numberOfIcons),这似乎是它实际占用的空间。

当在光标处输入其他字符:

enter image description here

这是更加古怪。如果图标有MouseListeners,则全部4个可见圆圈将触发该事件。如果我将框架拖到另一个窗口或最小化并恢复它,奇怪的部分消失,框架看起来像第一个图像(除了附加字符)。所以我猜,我的问题的这一部分是通过在正确的位置致电repaint()修复的 - 但是哪里?

这是产生图像上面的代码中看出:

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import java.awt.RenderingHints; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextPane; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.Style; 
import javax.swing.text.StyleConstants; 
import javax.swing.text.StyleContext; 
import javax.swing.text.StyledDocument; 

public class TextPaneTestPanel extends JPanel { 

    private class myIcon extends JPanel { 
     private final int side; 
     private final int padding = 1; 

     public myIcon(int size) { 
      this.side = size - 2 * padding; 
      this.setSize(size, size); 
      this.setPreferredSize(getSize()); 
      this.setMinimumSize(getSize()); 
     } 

     public void paint(Graphics g) { 
      Graphics2D g2d = (Graphics2D) g.create(); 

      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

      g2d.setColor(Color.BLACK); 
      g2d.setStroke(new BasicStroke(2)); 
      g2d.drawOval(padding, padding, side, side); 
     } 
    } 

    private final JTextPane textPane; 

    public TextPaneTestPanel() { 

     textPane = new JTextPane(); 

     StyledDocument doc = textPane.getStyledDocument(); 
     Style def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE); 
     StyleConstants.setFontFamily(def, "Monospaced"); 

     Style regular = doc.addStyle("regular", def); 

     try { 
      doc.insertString(0, "abc", regular); 
      Style s1 = doc.addStyle("icon1", regular); 
      StyleConstants.setComponent(s1, new myIcon(20)); 
      doc.insertString(3, " ", s1); 
      doc.insertString(4, "def", regular); 
      Style s2 = doc.addStyle("icon2", regular); 
      StyleConstants.setComponent(s2, new myIcon(20)); 
      doc.insertString(7, " ", s2); 
     } catch (BadLocationException e1) { 
      e1.printStackTrace(); 
     } 

     this.setLayout(new GridBagLayout()); 
     this.add(textPane, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, 
       new Insets(4, 4, 4, 4), 0, 0)); 
    } 

    public static void main(String[] args) { 
     JFrame frame = new JFrame("Test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setResizable(false); 

     TextPaneTestPanel panel = new TextPaneTestPanel(); 

     frame.getContentPane().add(panel); 
     frame.setSize(300, 100); 
     frame.setVisible(true); 
    } 

} 

综上所述,我的问题:

  1. 什么导致了一个图标后出现的空间?

  2. 我在哪里添加repaint()revalidate()来解决图像#2中看到的问题?

P.S:我知道,我的“图标”未实现Icon,但它不应该是必要的,因为JTextPanes可以处理的Components种种。

回答

2

1.什么导致空间出现在图标之后?

好了,你有下面的代码:

this.setMinimumSize(getSize()); 

怎么样的最大尺寸?

如何解决图像#2中看到的问题?

自定义绘画是通过覆盖paintComponent()方法而不是paint()方法完成的,不要忘记调用super.paintComponent。

一个图标在这里更合适,因为你所做的只是自定义绘画。甚至是一个JComponent,但不是一个用于容纳其他组件的容器的JPanel。另外,你使用一个图标,你没有面板的尺寸问题,或者JComponent,因为该方法专门作为界面的一部分实现。

+0

自从我使用自定义绘画已经很久了,所以我不记得'paintComponent()'的正确函数。我一直在这个问题上好几天,但现在看到解决方案我觉得有点愚蠢。就最大尺寸而言:为什么这会导致该错误?我承认,我忘了设置它,但为什么最重要?尽可能扩大专家组的逻辑理由是什么? – nfs 2013-03-25 22:14:40

+0

为什么我在这种情况下没有使用'Icon'很简单:无法将'MouseListeners'添加到'Icons',但我需要为我的应用程序的功能。我做了,但请注意您的建议,以扩展'JComponent'而不是'JPanel'。 – nfs 2013-03-25 22:22:30