Java 如何在Swing JComponents中渲染分数

Java 如何在Swing JComponents中渲染分数,java,swing,fractions,jspinner,jformattedtextfield,Java,Swing,Fractions,Jspinner,Jformattedtextfield,基本上,Swing JC组件能够以这种形式显示分数形式的数字2/3。如何以最好的形式绘制分数,例如2⅔? 编辑 如图所示,我在JSpinner内部只有一个TableColumn和TableRow(也可以模拟普通JtextField),其中,TableRenderer可以是一些使用Html格式化的JTextComponent,在TableCellEdit事件中,TableEditor切换到普通的JFormattedTextField 还有其他方法吗?也可以使用纯J(格式化)文本字段 您必须找到

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

编辑

如图所示,我在
JSpinner
内部只有一个
TableColumn
TableRow
(也可以模拟普通
JtextField
),其中,
TableRenderer
可以是一些使用Html格式化的
JTextComponent
,在
TableCellEdit
事件中,
TableEditor
切换到普通的
JFormattedTextField


还有其他方法吗?也可以使用纯
J(格式化)文本字段

您必须找到一种字体,以您所称的最佳形式打印分数,然后编写一种方法,将分数的字符串转换为相应的最佳形式分数的字符代码。

经过反思,Unicode分数和中的Unicode分数的覆盖范围有限,可能有些过分。本例使用

附录:所示方法非常适合渲染混合数字。对于编辑,可以为文本组件中的计算器样式输入添加到
+
/
。我曾经对有理数建模,这可以用来计算有理表达式

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();
            }
        });
    }
}

导入java.awt.Color;
导入java.awt.EventQueue;
导入java.awt.GridLayout;
导入javax.swing.BorderFactory;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
/**@见https://stackoverflow.com/questions/7448216 */
公共类HTMLFractions扩展了JPanel{
私有静态int N=8;
公共HTMLFractions(){
setLayout(新的GridLayout(N,N,N,N));
this.setboorder(BorderFactory.createEmptyByOrder(N,N,N,N));
对于(int r=0;r
使用Java2D API。这本书是奥莱利关于它的一本好书

1-使用你喜欢的字体。 2-将所需的图示符(例如“2”“/”和“3”)转换为Java2D形状。 3-使用Java@d方法缩放形状并将其放置在一起

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

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

来吧,给我50英镑

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

非常感谢你的观点。下面是如何执行第一步的示例。它将显示如何从所选字体的字符中获取
entercode here
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();
    }
  }
}

您可以使用基于此的方法


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

特殊字体方法:

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

你需要一个好的字体编辑器

为分数的顶部数字创建十个数字,为中间数字创建一个特殊的斜线或线条符号,为底部数字创建十个数字

唯一的问题是它必须看起来很好,这需要顶部/斜线/和按钮的间距都接近在一起,实际上水平重叠。好消息是字体支持这一点,一个好的字体编辑器将支持这一点。swing文本组件可能没有。您需要编写自己的文本组件来查找一个已经允许您精确定位字体的组件。这是测试编辑/文字处理和文本排版之间的区别

但我还有另一个想法:)

你可以用单杠而不是斜杠来做分数

123
---
456
这样字体就不需要重叠,并且可以由编辑器以标准方式进行布局。诀窍是让上面的三个字符彼此相邻

1 2 3
- - -
4 5 6
所有组合都需要100个不同的字符

唯一的问题是(除了必须创建100个字符外),如果顶部有奇数个数字,底部有偶数个数字或虎钳体,则看起来是这样的:

 12
---
456

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;
}