在CalendarCanvas
课程中,我们的想法是在日历中的任何一天按下,一个表格将显示用户选择的当天的实际日期(而不仅仅是现在的日期)和表格下方将是与表格相关的图像(例如,6月21日(image.jpg
))。
我遇到两个问题。
第一,程序只喜欢一张Men.img
的图像。它将以所有三种形式显示该图像。其他两个图像根本不会显示。
我不明白,因为我首先开始使用一个表单和images.jpg
图像并且该图像有效。我所做的只是创建2个新表格并切换图像的顺序。
我甚至缩小了尺寸(宽度/高度和KB)以匹配Men.jpg
,但它仍然没有显示。 ImageItem构造函数中的字符串甚至不显示。
最后,如何创建calendar.getSelectedDate().toString()
方法的新实例以显示新用户选择日期,以便在用户选择其他日期时将其放在图像上方?
在keyPressed
方法中,已注释掉的新Alert实例将为我执行此操作,但我不想要提醒,我希望它是与用户选择的日期相关的表单标题
以下是我的代码:
类CalendarMidlet:
import java.io.IOException;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
/**
* @author addylesson
*/
public class CalendarMidlet extends MIDlet {
private Display mydisplay;
private Command f;
private Displayable d;
public CalendarMidlet(){}
public void startApp() {
d = new CalendarCanvas(this);
f = new Command("Exit", Command.EXIT, 0);
d.addCommand(f);
d.setCommandListener(new CommandListener()
{
public void commandAction(Command c, Displayable s)
{
if(c == f)
notifyDestroyed();
}
} );
mydisplay = Display.getDisplay(this);
mydisplay.setCurrent(d);
}
public void startOver() {
final Displayable d = new CalendarCanvas(this);
d.addCommand(f);
d.setCommandListener(new CommandListener()
{
public void commandAction(Command c, Displayable s)
{
if(c == f)
notifyDestroyed();
}
} );
mydisplay.setCurrent(d);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
类CalendarCanvas:
import java.io.IOException;
import java.util.Date;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class CalendarCanvas extends Canvas
{
CalendarWidget calendar = null;
CalendarMidlet midlet = null;
private Alert alert;
private List mList;
private Command f,e,n;
private Display mydisplay;
private Form form;
private Form form2;
private Form form3;
private ImageItem imageItem;
private ImageItem imageItem2;
private ImageItem imageItem3;
public CalendarCanvas(final CalendarMidlet m)
{
String day = calendar.getSelectedDate().toString();
this.midlet = m;
calendar = new CalendarWidget(new Date());
calendar.headerFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_LARGE);
calendar.weekdayFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_MEDIUM);
calendar.weekdayBgColor = 0xccccff;
calendar.weekdayColor = 0x0000ff;
calendar.headerColor = 0xffffff;
form = new Form(day);
form2 = new Form("New Page");
form3 = new Form("New Page");
try
{
imageItem = new ImageItem(
"Men In Black 3: ",
Image.createImage("Men.jpg"),
ImageItem.LAYOUT_DEFAULT,
"DuKe");
form.append(imageItem);
} catch(Exception s) {}
try
{
imageItem2 = new ImageItem(
"Jordon vs Knicks: ",
Image.createImage("images.jpg"),
ImageItem.LAYOUT_DEFAULT,
"Not");
form2.append(imageItem2);
} catch(Exception s) {}
try
{
imageItem3 = new ImageItem(
"Horoscope: ",
Image.createImage("Men.jpg"),
ImageItem.LAYOUT_DEFAULT,
"DuKe");
form3.append(imageItem3);
} catch(Exception s) {}
alert = new Alert("Listen", "On this day "
+calendar.getSelectedDate().toString()+ "stuff happened", null, null);
alert.setTimeout(Alert.FOREVER);
n = new Command("Next", Command.SCREEN,0);
f = new Command("Back", Command.BACK, 0);
e = new Command("Exit", Command.EXIT, 1);
form.addCommand(f);
form.addCommand(n);
form2.addCommand(f);
form2.addCommand(n);
form3.addCommand(f);
form3.addCommand(e);
form.setCommandListener(new CommandListener()
{
public void commandAction(Command c, Displayable s)
{
if (c == f)
m.startOver();
if (c == e)
m.notifyDestroyed();
if (c == n)
Display.getDisplay(midlet).setCurrent(form2);
}
} );
form2.setCommandListener(new CommandListener()
{
public void commandAction(Command c, Displayable s)
{
if (c == f)
m.startOver();
if (c == e)
m.notifyDestroyed();
if (c == n)
Display.getDisplay(midlet).setCurrent(form3);
}
} );
form3.setCommandListener(new CommandListener()
{
public void commandAction(Command c, Displayable s)
{
if (c == f)
m.startOver();
if (c == e)
m.notifyDestroyed();
}
} );
calendar.initialize();
}
protected void keyPressed(int key)
{
int keyCode = getGameAction(key);
String day = calendar.getSelectedDate().toString();
if(keyCode == FIRE)
{
/*Display.getDisplay(midlet).setCurrent(
new Alert("Selected date",
day, null,
AlertType.CONFIRMATION)
);*/
Display.getDisplay(midlet).setCurrent(form);
}
else
{
calendar.keyPressed(keyCode);
repaint();
}
}
protected void paint(Graphics g)
{
g.setColor(0xff0000);
g.fillRect(0, 0, getWidth(), getHeight());
calendar.paint(g);
}
}
类CalendarWidget:
import java.util.Calendar;
import java.util.Date;
import javax.microedition.lcdui.*;
public class CalendarWidget
{
static final String[] MONTH_LABELS = new String[]{
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
};
static final String[] WEEKDAY_LABELS = new String[]{
"M", "T", "W", "T", "F", "S", "S"
};
/* starting week day: 0 for monday, 6 for sunday */
public int startWeekday = 0;
/* elements padding */
public int padding = 2;
/* cells border properties */
public int borderWidth = 4;
public int borderColor = 0x000000;
/* weekday labels properties */
public Font weekdayFont = Font.getDefaultFont();
public int weekdayBgColor = 0xcccccc;
public int weekdayColor = 0xffffff;
/* header (month-year label) properties */
public Font headerFont = Font.getDefaultFont();
public int headerBgColor = 0xff0000;
public int headerColor = 0xff0000;
/* cells properties */
public Font font = Font.getDefaultFont();
public int foreColor = 0xffffff;
public int bgColor = 0xcccccc;
public int selectedBgColor = 0x000000;
public int selectedForeColor = 0xff0000;
/* internal properties */
int width = 0;
int height = 0;
int headerHeight = 0;
int weekHeight = 0;
int cellWidth = 0;
int cellHeight = 0;
/* internal time properties */
long currentTimestamp = 0;
Calendar calendar = null;
int weeks = 0;
public CalendarWidget(Date date)
{
calendar = Calendar.getInstance();
//we'll see these 2 methods later
setDate(date);
initialize();
}
public Date getSelectedDate()
{
return calendar.getTime();
}
public void setDate(Date d)
{
currentTimestamp = d.getTime();
calendar.setTime(d);
//weeks number can change, depending on week starting day and month total days
this.weeks = (int)Math.ceil(((double)getStartWeekday() + getMonthDays()) / 7);
}
public void setDate(long timestamp)
{
setDate(new Date(timestamp));
}
void initialize()
{
//let's initialize calendar size
this.cellWidth = font.stringWidth("MM") + 3 * padding;
this.cellHeight = font.getHeight() + 15 * padding;
this.headerHeight = headerFont.getHeight() + 2 * padding;
this.weekHeight = weekdayFont.getHeight() + 2 * padding;
this.width = 7 * (cellWidth + borderWidth) + borderWidth;
initHeight();
}
void initHeight()
{
this.height =
headerHeight + weekHeight +
this.weeks * (cellHeight + borderWidth) + borderWidth;
}
int getMonthDays()
{
int month = calendar.get(Calendar.MONTH);
switch(month)
{
case 3:
case 5:
case 8:
case 10:
return 30;
case 1:
return calendar.get(Calendar.YEAR) % 4 == 0 && calendar.get(Calendar.YEAR) % 100 != 0 ? 29 : 28;
default:
return 31;
}
}
int getStartWeekday()
{
//let's create a new calendar with same month and year, but with day 1
Calendar c = Calendar.getInstance();
c.set(Calendar.MONTH, calendar.get(Calendar.MONTH));
c.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
c.set(Calendar.DAY_OF_MONTH, 1);
//we must normalize DAY_OF_WEEK returned value
return (c.get(Calendar.DAY_OF_WEEK) + 5) % 7;
}
public void keyPressed(int key)
{
switch(key)
{
case Canvas.UP:
go(-7);
break;
case Canvas.DOWN:
go(7);
break;
case Canvas.RIGHT:
go(1);
break;
case Canvas.LEFT:
go(-1);
break;
}
}
void go(int delta)
{
int prevMonth = calendar.get(Calendar.MONTH);
setDate(currentTimestamp + 86400000 * delta);
//we have to check if month has changed
//if yes, we have to recalculate month height
//since weeks number could be changed
if(calendar.get(Calendar.MONTH) != prevMonth)
{
initHeight();
}
}
public void paint(Graphics g)
{
//painting background
g.setColor(bgColor);
g.fillRect(0, 0, width, height);
//painting header (month-year label)
g.setFont(headerFont);
g.setColor(headerColor);
g.drawString(MONTH_LABELS[calendar.get(Calendar.MONTH)] + " " + calendar.get(Calendar.YEAR), width / 2, padding, Graphics.TOP | Graphics.HCENTER);
//painting week days labels
g.translate(0, headerHeight);
g.setColor(weekdayBgColor);
g.fillRect(0, 0, width, weekHeight);
g.setColor(weekdayColor);
g.setFont(weekdayFont);
for(int i = 0; i < 7; i++)
{
g.drawString(WEEKDAY_LABELS[(i + startWeekday) % 7],
borderWidth + i * (cellWidth + borderWidth) + cellWidth / 2,
padding,
Graphics.TOP | Graphics.HCENTER
);
}
g.translate(0, weekHeight);
g.setColor(borderColor);
for(int i = 0; i <= weeks; i++)
{
g.fillRect(0, i * (cellHeight + borderWidth), width, borderWidth);
}
for(int i = 0; i <= 7; i++)
{
g.fillRect(i * (cellWidth + borderWidth), 0, borderWidth, height - headerHeight - weekHeight);
}
int days = getMonthDays();
int dayIndex = (getStartWeekday() - this.startWeekday + 7) % 7;
g.setColor(foreColor);
int currentDay = calendar.get(Calendar.DAY_OF_MONTH);
for(int i = 0; i < days; i++)
{
int weekday = (dayIndex + i) % 7;
int row = (dayIndex + i) / 7;
int x = borderWidth + weekday * (cellWidth + borderWidth) + cellWidth / 2;
int y = borderWidth + row * (cellHeight + borderWidth) + padding;
if(i + 1 == currentDay)
{
g.setColor(selectedBgColor);
g.fillRect(
borderWidth + weekday * (cellWidth + borderWidth),
borderWidth + row * (cellHeight + borderWidth),
cellWidth, cellHeight);
g.setColor(selectedForeColor);
}
g.drawString("" + (i + 1), x, y, Graphics.TOP | Graphics.HCENTER);
if(i + 1 == currentDay)
{
g.setColor(foreColor);
}
}
g.translate(0, - headerHeight - weekHeight);
}
}
答案 0 :(得分:1)
您发布的代码段中没有明显的错误。
为了更容易找出当你的MIDlet变得如此复杂时可能出错的地方,添加日志记录语句并在模拟器监视控制台输出中运行它。
肯定需要在catch
块中添加日志记录。要找出我为什么要发表如此强烈的声明,请在Web上搜索 Java swallow exceptions 之类的内容。
我建议记录的其他要点在commandAction
以及调用setCurrent
时。在开发时,可以随意添加更多(keyPressed
看起来像是一个很好的候选者)。
public class Log {
// utility class to keep logging code in one place
public static void log (String message) {
System.out.println(message);
// when debugging at real device, S.o.p above can be refactored
// - based on ideas like one used here (with Form.append):
// http://stackoverflow.com/questions/10649974
// - Another option would be to write log to RMS
// and use dedicated MIDlet to read it from there
// - If MIDlet has network connection, an option is
// to pass log messages over the network. Etc etc...
}
}
// ... other classes...
// ...
catch (Exception e) {
Log.log("unexpected exception: [" + e + "]");
}
// ...
public void commandAction(Command c, Displayable s) {
Log.log("command: [" + c.getCommandLabel()
+ "] at screen: [" + d.getTitle() + "]");
// ...
}
// ...
Log.log("set current: [" + someDisplayable.getTitle() + "]");
mydisplay.setCurrent(someDisplayable);
// ...
protected void keyPressed(int key) {
Log.log("key pressed: [" + getKeyName(key) + "]");
// ...
}