如何在Swing JComponents中渲染分数

时间:2011-09-16 17:14:42

标签: java swing fractions jspinner jformattedtextfield

基本上Swing JComponents能够以这种形式2 2/3显示分数。如何以最好的形式绘制分数,例如2⅔?

修改

如我所见JTable JSpinner只有TableColumn一个TableRowJtextField(也可以模拟普通TableRenderer),其中JTextComponent TableCellEdit 1}}可以是使用Html格式化的TableEditor部分,JFormattedTextField事件J(Formatted)TextField可以转换为普通{{1}},

还有另一种方式,是否可以使用普通{{1}} ???

6 个答案:

答案 0 :(得分:23)

在反思中,Latin-1 SupplementNumber Forms中的Unicode分数提供有限的覆盖范围,fancy equations可能过度。此示例使用HTML in Swing Components

附录:所显示的方法非常适合渲染混合数字。要进行编辑,可以为文本组件中的计算器样式输入添加key bindings+/。我使用org.jscience.mathematics.number.Rational来模拟有理数,而parser可以用来评估理性表达式。

HTMLFractions

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/** @see https://stackoverflow.com/questions/7448216 */
public class HTMLFractions extends JPanel {

    private static int N = 8;

    public HTMLFractions() {
        this.setLayout(new GridLayout(N, N, N, N));
        this.setBorder(BorderFactory.createEmptyBorder(N, N, N, N));
        for (int r = 0; r < N; r++) {
            for (int c = 0; c < N; c++) {
                this.add(create(r + N, r + 1, c + 2));
            }
        }
    }

    private JLabel create(int w, int n, int d) {
        StringBuilder sb = new StringBuilder();
        sb.append("<html><body>");
        sb.append(w);
        sb.append("<sup>");
        sb.append(n);
        sb.append("</sup>");
        sb.append("<font size=+1>/<font size=-1>");
        sb.append("<sub>");
        sb.append(d);
        sb.append("</sub>");
        sb.append("</html></body>");
        JLabel label = new JLabel(sb.toString(), JLabel.CENTER);
        label.setBorder(BorderFactory.createLineBorder(Color.lightGray));
        return label;
    }

    private void display() {
        JFrame f = new JFrame("HTMLFractions");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new HTMLFractions().display();
            }
        });
    }
}

答案 1 :(得分:5)

使用Java2D API。这是奥莱利的一本很好的书。

1-使用您喜欢的字体。 2-将您需要的字形(例如“2”“/”和“3”)转换为Java2D形状。 3-使用Java @ d方法缩放和放置形状

4-这部分取决于组件。我认为很多组件都采用某种图像而不是文本。将您的形状转换为适合您的组件的任何形状。

5-如果你做得好,这应该看起来很专业:)

来吧给我50 !!!

=============

非常感谢你的观点。以下是如何执行第一步的示例。它将展示如何从您选择的字体中的字符中获取enter code here Shape的实例。

获得Shape后,您可以使用Graphics2D创建所需的图像(缩放,撰写等)。所有的swing组件都不同,但都有图形上下文。使用图形内容,您可以在任何Swing组件上绘制。您还可以制作透明图层,并将传输JPanel粘贴到您想要的任何内容上。如果你只是想在标签上显示一个很容易的分数。如果你有某种文字处理器,那很难。

import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

public class Utils {

  public static Shape generateShapeFromText(Font font, char ch) {
    return generateShapeFromText(font, String.valueOf(ch));
  }

  public static Shape generateShapeFromText(Font font, String string) {
    BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2 = img.createGraphics();

    try {
      GlyphVector vect = font.createGlyphVector(g2.getFontRenderContext(), string);
      Shape shape = vect.getOutline(0f, (float) -vect.getVisualBounds().getY());

      return shape;
    } finally {
      g2.dispose();
    }
  }
}

答案 2 :(得分:5)

您可以使用基于此的方法 http://java-sl.com/fraction_view.html

唯一的区别是为分子和分母定位子视图。

答案 3 :(得分:4)

Unicode有一组字符,可以让您无需进行特殊格式化即可生成分数,例如⁴/₉或⁵⁶/ 10 0。

您可以设置一个上标数字数组和一个下标数字数组,并将您的数字转换为这些数字的字符串,然后将它们与中间的分数斜杠组合。

优点是它更通用(您可以在其他上下文中使用代码),并且结果往往看起来比您尝试使用HTML格式重现它时更好。当然,您需要在系统上安装Unicode字体,但大多数系统最近都会这样做。

代码中可能的实现:

    public String diagonalFraction(int numerator, int denominator) {
    char numeratorDigits[] = new char[]{
            '\u2070','\u00B9','\u00B2','\u00B3','\u2074',
            '\u2075','\u2076','\u2077','\u2078','\u2079'};
    char denominatorDigits[] = new char[]{
            '\u2080','\u2081','\u2082','\u2083','\u2084',
            '\u2085','\u2086','\u2087','\u2088','\u2089'};
    char fractionSlash = '\u2044';

    String numeratorStr = new String();
    while(numerator > 0){
        numeratorStr = numeratorDigits[numerator % 10] + numeratorStr;
        numerator = numerator / 10;
    }
    String denominatorStr = new String();
    while(denominator > 0){
        denominatorStr = denominatorDigits[denominator % 10] + denominatorStr;
        denominator = denominator / 10;
    }   
    return numeratorStr + fractionSlash + denominatorStr;
}

答案 4 :(得分:3)

你必须找到一个字体来打印你所称的最好的形式的分数,然后写一个方法将你的分数的字符串转换成相应的最好的形式分数的字符代码。

答案 5 :(得分:2)

特殊字体方法:

特殊字体方法也可能是一个非常好的解决方案。

您需要一个好的字体编辑器。

仅为分数的最高编号创建十个数字,为​​中间创建一个特殊的斜线或线符号,为底部数字创建十个数字。

唯一的问题是它必须看起来很好并且要求顶部/斜杠/和按钮的间距全部靠近在一起,实际上是水平重叠。好消息是字体支持这个,一个好的字体编辑器会。 swing文本组件可能不会。您需要编写自己的文本组件来查找已经让您精确定位字体的组件。这是测试编辑/文字处理和文字排版之间的差异。

但我还有另一个想法:)

你可以使用水平条而不是斜线来做分数。

123
---
456

这种方式字体不需要重叠,可以由编辑以标准方式布局。诀窍是让上面的三个字符彼此相邻。

1 2 3
- - -
4 5 6

因此,所有组合都需要100个不同的角色。

这个问题的唯一问题(除了必须创建100个字符)是如果您在顶部甚至在底部或vise诗中有和奇数个数字,它将如下所示:

 12
---
456