Как сделать рендеринг дроби в Swing JComponents - PullRequest
16 голосов
/ 16 сентября 2011

В основном Swing JComponents могут отображать числа в долях в этой форме 2 2/3.Как я могу нарисовать фракцию в лучшем виде, например, 2⅔?

.

РЕДАКТИРОВАТЬ

.

, как видите, у меня есть только один способ JTable внутри JSpinner с одним TableColumn и TableRow (который может имитировать обычный JtextField тоже), где TableRenderer может быть частью JTextComponent, отформатированным с использованием Html и при TableCellEdit событии TableEditorк равнине JFormattedTextField,

есть ли другой способ, возможно ли это и с простым J(Formatted)TextField тоже ???

Ответы [ 6 ]

23 голосов
/ 17 сентября 2011

При отражении, фракции Unicode среди Latin-1 Дополнения и Числовые формы предлагают ограниченное покрытие, а причудливые уравнения могут быть излишними.В этом примере используется HTML в компонентах Swing .

Приложение: Показанный подход довольно хорошо подходит для рендеринга смешанных чисел.Для редактирования можно добавить привязки клавиш к + и / для ввода в виде калькулятора в текстовом компоненте.Я использовал org.jscience.mathematics.number.Rational для моделирования рациональных чисел, и этот синтаксический анализатор можно адаптировать для оценки рациональных выражений.

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();
            }
        });
    }
}
5 голосов
/ 11 октября 2011

Вы можете использовать подход, основанный на этом http://java -sl.com / фракция_view.html

Единственная разница заключается в позиционировании подпредставлений для числителя и знаменателя.

5 голосов
/ 10 октября 2011

Используйте API Java2D. Это отличная книга от О'Рейли.

1- Используйте шрифт, который вам нравится. 2- Преобразуйте нужные глифы (например, «2» »/« и »3) в формы Java2D. 3- Используйте метод Java @ d для масштабирования и размещения фигур вместе

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

5- Это должно выглядеть очень профессионально, если вы хорошо справляетесь:)

Давай, дай мне 50 !!!

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

Большое спасибо за очки. Вот пример того, как сделать первый шаг. Он покажет, как получить экземпляр enter code here Shape от символа с выбранным шрифтом.

Когда у вас есть Shape Вы можете использовать Graphics2D для создания нужного изображения (масштабировать, компоновать и т. Д.). Все компоненты свинга разные, но все они имеют графический контекст. Используя графический контент, вы можете рисовать на любом компоненте 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();
    }
  }
}
4 голосов
/ 12 октября 2011

Unicode имеет набор символов, которые позволят вам создавать дроби без необходимости специального форматирования, например, ⁴⁄₉ или ⁵⁶⁄₁₀₀.

Вы можете установить массив цифр верхнего индекса и массив цифр нижнего индекса, преобразовать ваши числа в строки этих цифр, а затем объединить их с косой чертой между ними.

Преимущества в том, что он более общий (вы можете использовать код в других контекстах), и результат будет выглядеть лучше, чем если бы вы попытались воспроизвести его с использованием форматирования 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;
}
3 голосов
/ 16 сентября 2011

Вам нужно будет найти шрифт, который печатает дроби в том, что вы называете лучшей формой, а затем написать метод для преобразования строки символов вашей дроби в код символа соответствующей фракции самой красивой формы.

2 голосов
/ 11 октября 2011

Метод специальных шрифтов:

Метод специальных шрифтов также может быть очень хорошим решением.

Вам понадобится хороший редактор шрифтов.

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

Единственная проблема заключается в том, что он долженвыглядят хорошо, и это требует, чтобы расстояние между верхней / косой чертой / и кнопкой было близко друг к другу, фактически перекрывая горизонталь.Хорошей новостью является то, что шрифты поддерживают это, и хороший редактор шрифтов будет.Компоненты свинг-текста, вероятно, нет.Вам нужно написать свой собственный текстовый компонент, чтобы найти компонент, который уже позволяет вам точно позиционировать шрифты.Это различие между тестовым редактированием / обработкой текста и типографикой текста.

Но у меня также есть другая идея:)

Вы можете делать дроби с горизонтальной полосой вместо диагональной косой черты.

123
---
456

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

1 2 3
- - -
4 5 6

Таким образом, это сто различных символов, необходимых для всех комбинаций.

Единственная проблема с этим (в дополнениечтобы создать 100 символов), если у вас есть и нечетное количество цифр в верхней части и даже в нижнем или стихе тиски это будет выглядеть так:

 12
---
456
...