Как рендерить часть в Swing JComponents

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

.

ИЗМЕНИТЬ

.

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

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

Ответы

Ответ 1

При отражении, Unicode фракции среди Latin-1 Supplement и Числовые формы предлагают ограниченное покрытие, а причудливые уравнения могут быть чрезмерными. В этом примере используется 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();
            }
        });
    }
}

Ответ 2

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

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

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

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

Ответ 3

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

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

Ответ 4

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

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

Преимущества в том, что он более общий (вы можете использовать код в других контекстах), и результат будет выглядеть лучше, чем если бы вы попытались воспроизвести его с помощью форматирования HTML. Конечно, вам нужно иметь юникодные шрифты в вашей системе, но большинство систем в наши дни.

Возможная реализация в коде:

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

Ответ 5

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

Ответ 6

Специальный метод шрифтов:

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

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

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

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

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

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

123
---
456

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

1 2 3
- - -
4 5 6

Итак, вам нужно сотню разных символов для всех комбинаций.

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

 12
---
456