Непредвиденный вывод при добавлении двух чисел с плавающей запятой

Я написал следующий код C++:

float a, b;
int c;

a = 8.6;
b = 1.4;
c = a + b;

printf("%d\n", c);

Вывод: 10 .

Но при выполнении следующего кода:

float a, b;
int c;

a = 8.7;
b = 1.3;
c = a + b;

printf("%d\n", c);

Вывод: 9 .

В чем разница между ними, поскольку они дают разные выходы?

-121--1741772-

Почему заголовок JTable не появляется в изображении? Я предлагал совет по захвату изображения табличных данных на Java API или Tool для преобразования табличных данных в файл изображения PNG Оказывается, сложнее, чем я...

Я предлагал совет по захвату изображения табличных данных на Java API или инструменте для преобразования табличных данных в файл изображения PNG - когда ОП запросила образец кода. Оказывается, сложнее, чем я думал! Заголовок JTable исчезает из PNG, который записывает код.

PNG

PNG

Снимок экрана

enter image description here

import javax.swing.*;
import java.awt.Graphics;
import java.awt.BorderLayout;
import java.awt.image.BufferedImage;

import javax.imageio.ImageIO;
import java.io.File;

class TableImage {

    public static void main(String[] args) throws Exception {
        Object[][] data = {
            {"Hari", new Integer(23), new Double(78.23), new Boolean(true)},
            {"James", new Integer(23), new Double(47.64), new Boolean(false)},
            {"Sally", new Integer(22), new Double(84.81), new Boolean(true)}
        };

        String[] columns = {"Name", "Age", "GPA", "Pass"};

        JTable table = new JTable(data, columns);
        JScrollPane scroll = new JScrollPane(table);
        JPanel p = new JPanel(new BorderLayout());
        p.add(scroll,BorderLayout.CENTER);

        JOptionPane.showMessageDialog(null, p);

        BufferedImage bi = new BufferedImage(
            (int)p.getSize().getWidth(),
            (int)p.getSize().getHeight(),
            BufferedImage.TYPE_INT_RGB
            );

        Graphics g = bi.createGraphics();
        p.paint(g);

        JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(bi)));
        ImageIO.write(bi,"png",new File("table.png"));
    }
}

Примечание: Я проверил класс изображения экрана camickr и включил вызов метода doLayout (Component) . Метод полезен в том случае, если компонент Component никогда не реализовывался на экране, но не влияет на этот код (что приводит к появлению панели, содержащей таблицу на панели параметров, перед тем, как пытаться ее визуализировать).

Что необходимо для отображения заголовка таблицы?

Обновить 1

Изменение строки.

        p.paint(g);

.. в (с соответствующим импортом)..

        p.paint(g);
        JTableHeader h = table.getTableHeader();
        h.paint(g);

.. производит..

2nd try

Я продолжу его корректировать.

Обновление 2

kleopatra (стратегия 1) и camickr (стратегия 2) дали ответ каждый, оба из которых работают, и ни один из которых не требует добавления JTable к фиктивному компоненту (который является огромным взломом IMO).

В то время как 2 стратегии будут обрезаны (или расширены) до «только таблицы», 1-я стратегия захватит панель, содержащую таблицу. Это становится проблематичным, если таблица содержит много записей, отображающих изображение усеченной таблицы с полосой прокрутки.

В то время как стратегия 1 может быть еще больше подправлена, чтобы обойти это, мне действительно нравится аккуратная простота стратегии 2, поэтому она получает галочку.

Как указала Клеопатра, никакого «сдвига» не требовалось. Так что я попробую еще раз..

Обновить 3

Это изображение, созданное методами, предложенными camickr и kleopatra. Я бы поставил его дважды, но на мой взгляд, они идентичны (хотя я не сделал пиксельное сравнение).

JTable in Nimbus PLAF

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

import javax.imageio.ImageIO;
import java.io.File;

class TableImage {

    String[] columns = {"Name", "Age", "GPA", "Pass"};
    /** Any resemblance to persons living or dead is purely incidental. */
    Object[][] data = {
        {"André", new Integer(23), new Double(47.64), new Boolean(false)},
        {"Jeanie", new Integer(23), new Double(84.81), new Boolean(true)},
        {"Roberto", new Integer(22), new Double(78.23), new Boolean(true)}
    };

    TableImage() {
    }

    public JTable getTable() {
        JTable table = new JTable(data, columns);
        table.setGridColor(new Color(115,52,158));
        table.setRowMargin(5);
        table.setShowGrid(true);

        return table;
    }

    /** Method courtesy of camickr.
    https://stackoverflow.com/questions/7369814/why-does-the-jtable-header-not-appear-in-the-image/7375655#7375655
    Requires ScreenImage class available from..
    http://tips4java.wordpress.com/2008/10/13/screen-image/ */
    public BufferedImage getImage1(JTable table) {
        JScrollPane scroll = new JScrollPane(table);

        scroll.setColumnHeaderView(table.getTableHeader());
        table.setPreferredScrollableViewportSize(table.getPreferredSize());

        JPanel p = new JPanel(new BorderLayout());
        p.add(scroll, BorderLayout.CENTER);

        BufferedImage bi = ScreenImage.createImage(p);
        return bi;
    }

    /** Method courtesy of kleopatra.
    https://stackoverflow.com/questions/7369814/why-does-the-jtable-header-not-appear-in-the-image/7372045#7372045 */
    public BufferedImage getImage2(JTable table) {
        JScrollPane scroll = new JScrollPane(table);

        table.setPreferredScrollableViewportSize(table.getPreferredSize());

        JPanel p = new JPanel(new BorderLayout());
        p.add(scroll, BorderLayout.CENTER);

        // without having been shown, fake a all-ready
        p.addNotify();

        // manually size to pref
        p.setSize(p.getPreferredSize());

        // validate to force recursive doLayout of children
        p.validate();

        BufferedImage bi = new BufferedImage(p.getWidth(), p.getHeight(), BufferedImage.TYPE_INT_RGB);

        Graphics g = bi.createGraphics();
        p.paint(g);
        g.dispose();

        return bi;
    }

    public void writeImage(BufferedImage image, String name) throws Exception {
        ImageIO.write(image,"png",new File(name + ".png"));
    }

    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        TableImage ti = new TableImage();
        JTable table;
        BufferedImage bi;

        table = ti.getTable();
        bi = ti.getImage1(table);
        ti.writeImage(bi, "1");
        JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(bi)));

        table = ti.getTable();
        bi = ti.getImage2(table);
        ti.writeImage(bi, "2");
        JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(bi)));
    }
}

Оба достигают цели. С помощью метода camickr можно использовать дополнительные возможности ScreenImage API. С помощью метода Клеопатры - около десятка строк (меньше комментариев и белого пространства) чистого J2SE.

В то время как ScreenImage является классом, который я буду использовать и рекомендовать в будущем, другой подход с использованием основных J2SE, вероятно, будет использоваться для этого точного обстоятельства.

В то время как «тик» останется с camickr, награда собирается kleopatra.

27
задан Community 23 May 2017 в 12:02
поделиться