JOptionPane displaying HTML problems in Java

一世执手 提交于 2020-01-09 08:05:26

问题


Okay, so I have this code, it prompts a month and a year from the user and prints the calendar for that month. I'm having some problems though.

  1. the HTML font editing only affects the month.
  2. the days of the week are not aligned in columns correctly.

Thanks!

package calendar_program;

import javax.swing.JOptionPane;

public class Calendar {

public static void main(String[] args) {
    StringBuilder result=new StringBuilder();

    // read input from user
    int year=getYear();
    int month=getMonth();

    String[] allMonths={
            "", "January", "February", "March", "April", "May", "June",
            "July", "August", "September", "October", "November", "December"
    };

    int[] numOfDays= {0,31,28,31,30,31,30,31,31,30,31,30,31};

    if (month == 2 && isLeapYear(year)) numOfDays[month]=29;

    result.append("    "+allMonths[month]+ "  "+ year+"\n"+" S  M  Tu  W Th  F  S"+"\n");

    int d= getstartday(month, 1, year);

    for (int i=0; i<d; i++){
        result.append("    ");
                // prints spaces until the start day
    }
    for (int i=1; i<=numOfDays[month];i++){
        String daysSpace=String.format("%4d", i);
        result.append(daysSpace);
        if (((i+d) % 7==0) || (i==numOfDays[month])) result.append("\n");
    }
    //format the final result string
    String finalresult= "<html><font face='Arial'>"+result; 
    JOptionPane.showMessageDialog(null, finalresult);
}

//prompts the user for a year
public static int getYear(){
    int year=0;
    int option=0;
    while(option==JOptionPane.YES_OPTION){
        //Read the next data String data
        String aString = JOptionPane.showInputDialog("Enter the year (YYYY) :");
        year=Integer.parseInt(aString);
        option=JOptionPane.NO_OPTION;
    }
    return year;
}

//prompts the user for a month
public static int getMonth(){
    int month=0;
    int option=0;
    while(option==JOptionPane.YES_OPTION){
        //Read the next data String data
        String aString = JOptionPane.showInputDialog("Enter the month (MM) :");
        month=Integer.parseInt(aString);
        option=JOptionPane.NO_OPTION;
    }
    return month;
}

//This is an equation I found that gives you the start day of each month
public static int getstartday(int m, int d, int y){
    int year = y - (14 - m) / 12;
    int x = year + year/4 - year/100 + year/400;
    int month = m + 12 * ( (14 - m) / 12 ) - 2;
    int num = ( d + x + (31*month)/12) % 7;
    return num;
}

//sees if the year entered is a leap year, false if not, true if yes
public static boolean isLeapYear (int year){
    if ((year % 4 == 0) && (year % 100 != 0)) return true;
    if (year % 400 == 0) return true;
    return false;
}
}

回答1:


Here's a rather stupid idea.

Rather then formatting your results using spaces, which may be affected by variance in the individual font widths of a variable width font...use a HTML table instead, or a JTable, or JXMonthView from the SwingX project

HTML Table

String dayNames[] = {"S", "M", "Tu", "W", "Th", "F", "S"};
result.append("<html><font face='Arial'>");
result.append("<table>");
result.append("<tr>");
for (String dayName : dayNames) {
    result.append("<td align='right'>").append(dayName).append("</td>");
}
result.append("</tr>");
result.append("<tr>");
for (int i = 0; i < d; i++) {
    result.append("<td></td>");
}
for (int i = 0; i < numOfDays[month]; i++) {
    if (((i + d) % 7 == 0)) {
        result.append("</tr><tr>");
    }
    result.append("<td align='right'>").append(i + 1).append("</td>");
}
result.append("</tr>");
result.append("</table>");

result.append("</html>");

JTable Example

MyModel model = new MyModel();

List<String> lstRow = new ArrayList<String>(7);
for (int i = 0; i < d; i++) {
    lstRow.add("");
}
for (int i = 0; i < numOfDays[month]; i++) {
    if (((i + d) % 7 == 0)) {
        model.addRow(lstRow);
        lstRow = new ArrayList<String>(7);
    }
    lstRow.add(Integer.toString(i + 1));
}

if (lstRow.size() > 0) {
    while (lstRow.size() < 7) {
        lstRow.add("");
    }
    model.addRow(lstRow);
}

JTable table = new JTable(model);
// Kleopatra is so going to kill me for this :(
Dimension size = table.getPreferredScrollableViewportSize();
size.height = table.getRowCount() * table.getRowHeight();
table.setPreferredScrollableViewportSize(size);

JOptionPane.showMessageDialog(null, new JScrollPane(table));

public static class MyModel extends AbstractTableModel {

    public static final String[] DAY_NAMES = {"S", "M", "Tu", "W", "Th", "F", "S"};
    private List<List<String>> lstRowValues;

    public MyModel() {
        lstRowValues = new ArrayList<List<String>>(25);
    }

    @Override
    public int getRowCount() {
        return lstRowValues.size();
    }

    @Override
    public String getColumnName(int column) {
        return DAY_NAMES[column];
    }

    @Override
    public int getColumnCount() {
        return 7;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        List<String> rowData = lstRowValues.get(rowIndex);
        return rowData.get(columnIndex);
    }

    public void addRow(List<String> lstValues) {
        lstRowValues.add(lstValues);

        fireTableRowsInserted(getRowCount(), getRowCount());
    }
}

Or you can go have a look at JXMonthView




回答2:


There are a couple issues I noticed. For one, instead of getting your own days in the month or leap year info, you could use the java.util.Calendar class, which will do that for you.

Also, \n newlines don't behave well when interspersed with HTML formatting, so try using < br/> instead. This is causing the font choice to work improperly.

It looks like extra spaces also get stripped, so surrounding everything with a < pre> tag will fix that.



来源:https://stackoverflow.com/questions/12702689/joptionpane-displaying-html-problems-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!