cannot find symbol : method setCurrent(Kalkulator) - java

I'm trying to connect my java files so I can create an app that uses main menu, but this error always persist, no matter what I do. here's my code:
Zakat.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Zakat extends MIDlet
{
private Display display;
public FormLoading FormLoading;
public Keluar Keluar;
public MenuUtama MenuUtama;
public Pengenalan Pengenalan;
public Kalkulator Kalkulator;
public About About;
public Profil Profil;
//public CanvasAwal canvasAwal;
public Zakat()
{
display = Display.getDisplay(this);
FormLoading = new FormLoading(this);
Keluar = new Keluar(this);
MenuUtama = new MenuUtama(this);
Pengenalan = new Pengenalan(this);
Kalkulator = new Kalkulator(this);
About = new About(this);
Profil = new Profil(this);
//canvasAwal = new CanvasAwal(this);
}
public void startApp()
{
Display.getDisplay(this).setCurrent(FormLoading);
}
public void pauseApp()
{
}
public void destroyApp(boolean b)
{
}
}
MenuUtama.java
import java.io.IOException;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
class MenuUtama extends List implements CommandListener
{
public Zakat app;
Ticker tc;
public MenuUtama(Zakat app)
{
super("Menu Utama",List.IMPLICIT);
this.app = app;
Image img=null;
Image img1=null;
Image img2=null;
try
{
img = Image.createImage("/icon1.png");
}
catch(Exception e)
{
}
append("Pengenalan Zakat",img);
append("Kalkulator",img);
append("About",img);
append("Profil",img);
append("Keluar",img);
addCommand(new Command("Pilih",Command.OK,0));
addCommand(new Command("Keluar",Command.EXIT,0));
tc = new Ticker ("Silahkan Pilih");
setTicker(tc);
setCommandListener(this);
}
public void commandAction (Command c, Displayable d)
{
switch(getSelectedIndex())
{
case 0:
Display.getDisplay(app).setCurrent(app.Pengenalan);
break;
case 1:
Display.getDisplay(app).setCurrent(app.Kalkulator);
break;
case 2:
Display.getDisplay(app).setCurrent(app.About);
break;
case 3:
Display.getDisplay(app).setCurrent(app.Profil);
break;
case 4:
Display.getDisplay(app).setCurrent(app.Keluar);
break;
}
switch( c.getCommandType())
{
case Command.EXIT:
Display.getDisplay(app).setCurrent(app.Keluar);
break;
}
}
}
Kalkulator.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.io.IOException;
public class Kalkulator extends MIDlet implements CommandListener,ItemCommandListener
{
Zakat app;
private Command cmdHitung = new Command("Hitung",Command.ITEM,1);
private Command exitCommand = new Command("Kembali",Command.EXIT,1);
private Display display;
private Form form = new Form("kalkulator");
private TextField var;
private TextField hasil;
public Kalkulator(Zakat app)
{
var = new TextField("Penghasilan selama 1 Tahun",null,12,TextField.NUMERIC);
hasil = new TextField("Zakat yang harus dibayarkan",null, 12 ,TextField.NUMERIC);
form.append(var);
form.append(hasil);
form.setCommandListener(this);
}
public void startApp()
{
if(display==null)
{
display = Display.getDisplay(this);
display.setCurrent(form);
}
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
public void commandAction (Command c, Displayable d)
{
switch (c.getCommandType())
{
case Command.EXIT:
Display.getDisplay(app).setCurrent(app.MenuUtama);
break;
}
}
public void commandAction(Command c, Item item)
{
if(c.equals(this.cmdHitung))
{
int hsl = Integer.parseInt(var.getString()) / 40;
hasil.setString(Integer.toString(hsl));
}
}
}
please help, and thanks before.

You appear to be calling the setCurrent method on a Display instance. That method expects an argument that is an instance of some class that implements Displayable. But Kalculator is a Midlet instance and that does not implement Displayable. Hence the compilation error.
I'm not a J2ME developer, but it looks like you should be passing setCurrent a Window object; e.g. a Form, Alert, List or TextBox.

Related

How to change the icon of a dynamically generated JButton

I have this java swing program, and im trying to figure out how can i create a button that upon clicking it will clear the text areas & change the icon of the person to put their hand down.
The buttons are dynamically generated using a for loop
And this
// To create buttons
for(int i=0 ; i < list.length; i++){
Participant pa = list[i];
JButton b = new JButton(pa.getNameButton(),participant);
b.addActionListener(e ->
{
String s = pa.toString() + questionPane.getText();
final ImageIcon raise = resizeIcon(new ImageIcon("src/raise.png"),30,30);
b.setIcon(raise);
JOptionPane.showMessageDialog(null,s,"Welcome to Chat Room",JOptionPane.INFORMATION_MESSAGE,pa.getImage());
});
p.add(b);
}
// Clear button logic
clearButton.addActionListener(e ->{
questionPane.setText("");
hostPane.setText("");
});
Okay, this is going to be a bit of fun.
The following example decouples much of the concept and makes use of a basic "observer pattern" to notify interested parties that the state has changed (ie, the chat's been cleared).
This is a basic concept where by you decouple the "what" from the "how", ie, "what" it is you want done (update the model) from the "how" it gets done (ie, button push). This makes it easier to adapt to more complex systems.
The example contains a ChatService, which has a single listener, which, for this example, simple tells interested parties that the chat has been cleared.
A more complex solution might have the ChatService generating events for when a user "raises" their hand, which allows the interested parties to deal with it in what ever way is relevant to them.
The example makes use of the Action API to decouple the work performed by each action from the UI itself. This helps create a single unit of work which is easier to deal with when you have a dynamic data set.
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
ChatService chatService = new ChatService();
JPanel panel = new JPanel();
String[] names = new String[] {"Bryan", "Alan", "George", "Henry"};
List<PeopleAction> actions = new ArrayList<>(names.length);
for (String name : names) {
PeopleAction action = new PeopleAction(chatService, name, false);
actions.add(action);
}
Random rnd = new Random();
actions.get(rnd.nextInt(names.length)).setRaised(true);
for (Action action : actions) {
JButton btn = new JButton(action);
panel.add(btn);
}
setLayout(new GridLayout(2, 1));
add(panel);
JPanel hostPane = new JPanel();
JButton clearButton = new JButton(new ClearAction(chatService));
hostPane.add(clearButton);
add(hostPane);
}
}
public class ChatService {
private List<ChatListener> listeners = new ArrayList<>(25);
public void addChatListeners(ChatListener listener) {
listeners.add(listener);
}
public void removeChatListener(ChatListener listener) {
listeners.remove(listener);
}
protected void fireChatCleared() {
if (listeners.isEmpty()) {
return;
}
for (ChatListener listener : listeners) {
listener.chatCleared();
}
}
public void clear() {
// Do what's required
fireChatCleared();
}
}
public interface ChatListener {
public void chatCleared();
}
public class PeopleAction extends AbstractAction implements ChatListener {
private String name;
private boolean raised;
public PeopleAction(ChatService chatService, String name, boolean raised) {
// You can use either LARGE_ICON_KEY or SMALL_ICON to set the icon
this.name = name;
if (raised) {
putValue(NAME, "* " + name);
} else {
putValue(NAME, name);
}
chatService.addChatListeners(this);
}
public void setRaised(boolean raised) {
if (raised) {
putValue(NAME, "* " + name);
} else {
putValue(NAME, name);
}
}
public boolean isRaised() {
return raised;
}
#Override
public void actionPerformed(ActionEvent evt) {
// Do what ever needs to be done
setRaised(!isRaised());
}
#Override
public void chatCleared() {
setRaised(false);
}
}
public class ClearAction extends AbstractAction {
private ChatService chatService;
public ClearAction(ChatService chatService) {
this.chatService = chatService;
putValue(NAME, "Clear");
}
#Override
public void actionPerformed(ActionEvent evt) {
chatService.clear();
}
}
}

How do you create a custom button in lanterna?

I've created a simple terminal app using lanterna that simply displays a custom button. But even though in the custom button's class I extend the Button class and override the Button class' createDefaultRenderer method to return an instance of the Button class' FlatButtonRenderer class, it is displaying the button using the DefaultButtonRenderer class.
Can you help me understand how to create a custom button in lanterna that displays the button using the FlatButtonRenderer?
import java.io.IOException;
import java.util.ArrayList;
import com.googlecode.lanterna.terminal.*;
import com.googlecode.lanterna.screen.*;
import com.googlecode.lanterna.gui2.*;
class Test {
public static void main(String[] args) {
DefaultTerminalFactory terminalFactory = new DefaultTerminalFactory();
Screen screen = null;
try {
screen = terminalFactory.createScreen();
screen.startScreen();
final WindowBasedTextGUI textGUI = new MultiWindowTextGUI(screen);
final Window window = new GUIAppWindow();
textGUI.addWindowAndWait(window);
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if(screen != null) {
try {
screen.stopScreen();
}
catch(IOException e) {
e.printStackTrace();
}
}
}
}
private static class GUIAppWindow extends BasicWindow {
GUIAppWindow() {
ArrayList<Window.Hint> hints = new ArrayList<>();
hints.add(Window.Hint.CENTERED);
setHints(hints);
Panel mainPanel = new Panel(new LinearLayout(Direction.VERTICAL));
XButton b = new XButton(new String("."));
b.addListener(new ButtonHandler("data"));
mainPanel.addComponent(b);
this.setComponent(mainPanel);
}
private class XButton extends Button {
public XButton(String label) {
super(label);
}
#Override
protected ButtonRenderer createDefaultRenderer() {
return new Button.FlatButtonRenderer();
}
}
private class ButtonHandler implements Button.Listener {
final String loc;
ButtonHandler(String loc) {
this.loc = loc;
}
public void onTriggered(Button button) {
button.setLabel(button.getLabel().equals(".") ? "x" : new String("."));
}
}
}
}
I believe the correct way to use FlatButtonRenderer is to call setRenderer().
private class XButton extends Button {
public XButton(String label) {
super(label);
setRenderer(new Button.FlatButtonRenderer());
}
}

How to validate the YouTube embedded link only using regular expression

I am using the YouTube embedded link in my website .I want to validate the link as if user paste something else other then embedded link then it should give me an alert invalid URL. I have used so many regex some has already in my code i have commented it .I want regular expression of YouTube embedded link only. Here i my code:
package com.edubot.client.lecture;
import gwt.material.design.client.ui.MaterialButton;
import gwt.material.design.client.ui.MaterialTextBox;
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Widget;
public class EmbeddedLink extends Composite {
private static EmbeddedLinkUiBinder uiBinder = GWT
.create(EmbeddedLinkUiBinder.class);
interface EmbeddedLinkUiBinder extends UiBinder<Widget, EmbeddedLink> {
}
#UiField MaterialButton buttonembedded;
// #UiField IFrameElement youtubevideo;
#UiField HTMLPanel htmlpanel;
#UiField MaterialTextBox textbox ;
public EmbeddedLink() {
super();
sinkEvents( Event.ONPASTE );
initWidget(uiBinder.createAndBindUi(this));
}
#Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
switch (event.getTypeInt()) {
case Event.ONPASTE: {
Timer timer = new Timer() {
#Override
public void run() {
// TODO Auto-generated method stub
onPasted();
Window.alert("paste");
}
};
timer.schedule(1000);
}
}
}
// #UiHandler("buttonembedded")
// void onClick(ClickEvent e) {
//// onPasted();
// }
private void onPasted(){
// youtubevideo.setSrc(addEmbeddedLink());
Window.alert("msg1");
if(testEmbeddedLink()) {
String link=textbox.getText().trim();
htmlpanel.getElement().setInnerHTML(link);
Window.alert("Valid URL");
} else {
Window.alert("Invalid URL");
}
}
public boolean testEmbeddedLink(){
String link=textbox.getText().trim();
Window.alert("msg");
String patternString = "(?:http(?:s)?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com\/)(?:)(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)\/[a-zA-Z0-9\-]*";
// String patternString = "<iframe title='YouTube video player' width='' height='' src='http://www.youtube.com/embed/$1' frameborder='0' allowfullscreen='1'></iframe>";
// String patternString = "~<iframe.+?src="https?://www.youtube.com/embed/([a-zA-Z0-9_-]{11})"[^>]+?></iframe>~i";
boolean result = link.matches(patternString);
return result;
}
// "youtube.com/(?<=v|embed\\)?[a-zA-Z0-9]+[^#\\&\\?]*";
// "(?<=youtu.be/?<=v|embed\\/)?[a-zA-Z0-9]+[^#\\&\\?]*";
// "(https?://)?(www\\.)?(yotu\\.be/|youtube\\.com/)?((.+/)?(watch(\\?v=|.+&v=))?(v=)?)([\\w_-]{11})(&.+)?"
// (\"http:\/\/www\.youtube\.com\/v\/\w{11}\&rel\=1\");
// (https?://www.youtube(?:-nocookie)?.com/(?:v|embed)/([a-zA-Z0-9-]+).*)"
// /<iframe.+?src="http://www.youtube.com/embed/([a-zA-Z0-9_-]{11})"[^>]+?>";</iframe>/i";
// "(?:youtube.com)\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})\W";
// "s*(https?://www.youtube(?:-nocookie)?.com/(?:v|embed)/([a-zA-Z0-9-]+).*) ";
// "^.*((youtu.be"+ "\\/)" + "|(v\\/)|(\\/u\\/w\\/)|(embed\\/)|(watch\\?))\\??v?=?([^#\\&\\?]*)
}
private String getYouTubeUrl(String text)
{
String finalUrl = null;
String p = "(//www.youtube(?:-nocookie)?.com/(?:v|embed)/([a-zA-Z0-9-_]+).*)";
if(text.contains("src"))
{
if(text.contains("//") && text.contains("frameborder"))
{
int startpos = text.indexOf("/", text.indexOf("src="));
int endpos = text.indexOf("frameborder");
String url=text.substring(startpos, endpos-2);
if(url.matches(p))
{
finalUrl = url;
}
else
{
Window.alert("You have entered a wrong embed code");
}
}
else
{
Window.alert("You have entered a wrong embed code");
}
}
else
{
Window.alert("You have entered a wrong embed code");
}
return finalUrl;
}

ValueChangeEvent not received my Composite Radio Button Group?

When I use two radio buttons with the same name then they are in a group. If one gets selected the other one gets unselected.
I want to build my own Radio Button Widget which is represented by the following code.
How can I achieve that if more than one of my widgets have the same name only one is selected just like for normal radio buttons that are grouped?
public class MyRadioButton extends Composite implements HasText, HasName, HasValueChangeHandlers<Boolean>, HasValue<Boolean> {
private FlowPanel picker;
private boolean isChecked;
public MyRadioButton() {
picker = new FlowPanel();
initWidget(picker);
addValueChangeHandler(new ValueChangeHandler<Boolean>() {
#Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
ValueChangeEvent.fire(MyRadioButton.this, isChecked);
}
});
}
#Override
public void setValue(Boolean value, boolean fireEvents) {
...
if (fireEvents) {
ValueChangeEvent.fire(MyRadioButton.this, value);
}
}
}
Do you solved your problem? If not this could help
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.RadioButton;
public class MyRadioButton extends Composite implements
DeselectOtherRadioButtonsHandler {
private RadioButton rb;
private String radioButtonGroup;
public MyRadioButton(String radioButtonGroup) {
rb = new RadioButton("Foo Button");
getEventBus().addHandler(DeselectOtherRadioButtonsEvent.getType(), this);
rb.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
#Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
if (event.getValue().booleanValue()) {
// deselect other in same group
getEventBus().fireEvent(new DeselectOtherRadioButtonsEvent(radioButtonGroup);
}
}
});
}
#Override
public void onDeselectOtherRadioButtons(DeselectOtherRadioButtonsEvent event) {
// Same RadioButton Group?
if (radioButtonGroup.equalsIgnoreCase(event.getRadioButtonGroup())) {
rb.setValue(false);
}
}
}
class DeselectOtherRadioButtonsEvent extends
GwtEvent<DeselectOtherRadioButtonsHandler> {
private final static Type<DeselectOtherRadioButtonsHandler> TYPE = new Type<DeselectOtherRadioButtonsHandler>();
private final String radioButtonGroup;
public DeselectOtherRadioButtonsEvent(String radioButtonGroup) {
this.radioButtonGroup = radioButtonGroup;
}
public String getRadioButtonGroup() {
return radioButtonGroup;
}
#Override
public Type<DeselectOtherRadioButtonsHandler> getAssociatedType() {
return TYPE;
}
#Override
protected void dispatch(DeselectOtherRadioButtonsHandler handler) {
handler.onDeselectOtherRadioButtons(this);
}
}
interface DeselectOtherRadioButtonsHandler extends EventHandler {
void onDeselectOtherRadioButtons(DeselectOtherRadioButtonsEvent event);
}

Blinking background rows of TableViewer or TreeViewer in SWT

I need the ability to have a blinking (red, maybe more colors) background for rows in a TableViewer/TreeViewer. What are the best options?
There may be more than one row blinking, the blinking MUST be synchron and I need two blinking modes, fast and slow.
I would do something similar to this. Update the elements that you need to change the colors for at a regular interval. At each update toggle the colors depending on how you want them to flash.
void scheduleColorChange(final Color colors[], final int startIndex, final int changeInterval)
{
getDisplay().timerExec(changeInterval, new Runnable()
{
public void run()
{
Object[] elements = getColorChangingElements();
setColorsForFlashingElements(elements, colors[index%colors.length]);
getViewer().update(elements);
scheduleColorChange(colors, startIndex+1, changeInterval)
}
});
}
and the have you label provider implement IColorProvider.
Howdy, this is a fast hack that shows the idea, improvable in many ways. I show the three classes doing the job. If you want I can provide an exported source plugin ready to install into your eclipse workbench tomorrow. Here are the core classes:
import java.util.TimerTask;
import org.eclipse.jface.resource.ColorDescriptor;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.ui.PlatformUI;
public class Blinker extends LabelProvider implements ITableLabelProvider, IColorProvider {
private final TableViewer viewer;
public Blinker(TableViewer viewer){
this.viewer = viewer;
}
// this is just a lousy way to store blink_on/blink_off...
private byte state;
// there must be a better way to get a color...
final static Color red = ColorDescriptor.createFrom(new RGB(255,0,0)).createColor(PlatformUI.getWorkbench().getDisplay());
final static Color green = ColorDescriptor.createFrom(new RGB(0,255,0)).createColor(PlatformUI.getWorkbench().getDisplay());
private final TimerTask task = new TimerTask(){
#Override
public void run() {
state++;
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable(){
public void run() {
viewer.refresh();
}
});
}
};
private Timer t;
synchronized byte getState(){
return state;
}
#Override
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
#Override
public String getColumnText(Object element, int columnIndex) {
return ((Element) element).text;
}
#Override
public Color getBackground(Object object) {
Element element = (Element) object;
if (element.isBlinking()){
return getState() % 2 == 0 ? Blinker.red : Blinker.green;
} else {
return Blinker.green;
}
}
#Override
public Color getForeground(Object element) {
return null;
}
public void start() {
t = new Timer();
t.schedule(task, 200, 1000);
}
public void stop() {
t.cancel();
t = null;
}
}
This is a sample model class. Blink state is stored within the object, but you might want to improve this by using some sort of Adapter:
package com.example.blinker;
public class Element {
private boolean blinking;
public final String text;
public Element(String string, boolean b) {
this.text = string;
this.blinking = b;
}
public synchronized boolean isBlinking(){
return blinking;
}
public synchronized void setBlinking(boolean b){
this.blinking = b;
}
public static final Element[] sampledata = new Element[] {
new Element("Merkur", false),
new Element("Venus", true),
new Element("Erde", false),
new Element("Mars", true),
new Element("Jupiter", false),
new Element("Saturn", true),
new Element("Uranus", false),
new Element("Neptun", true),
new Element("Pluto", false),
};
}
And finally a TableViewer embedded in a View, making use of the two above:
package com.example.blinker.views;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
import com.example.blinker.Blinker;
import com.example.blinker.Element;
public class SampleView extends ViewPart {
public static final String ID = "com.example.blinker.views.SampleView";
private TableViewer viewer;
private Blinker blinker;
class ViewContentProvider implements IStructuredContentProvider {
public void inputChanged(Viewer v, Object oldInput, Object newInput) {}
public void dispose() {}
public Object[] getElements(Object parent) {
return Element.sampledata;
}
}
public void createPartControl(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
viewer.setContentProvider(new ViewContentProvider());
blinker = new Blinker(viewer);
viewer.setLabelProvider(blinker);
viewer.setInput(new Object());
blinker.start();
}
public void setFocus() {
viewer.getControl().setFocus();
}
public void dispose() {
blinker.stop();
}
}
You should have a construction that resembles something like this:
LinkedList<Row> rows = new LinkedList<Row>();
Thread blinker = null;
public void start() {
blinker = new Thread() {
public void run() {
while(!this.interrupted()) {
try {
synchronized (rows) {
for (Row row : rows) {
row.setForegroundColor(color1);
}
}
Thread.sleep(500);
synchronized (rows) {
for (Row row : rows) {
row.setForegroundColor(color2);
}
}
Thread.sleep(500);
} catch (InterruptException e) {
break;
}
}
}
};
blinker.start();
}
public void stop() {
if (blinker != null) {
blinker.interrupt();
}
}
public void add(Row row) {
synchronized (rows) {
if (!rows.contains(row)) {
rows.add(row);
}
}
}
public void remove(Row row) {
synchronized (rows) {
rows.remove(row);
}
}
When the Shell displays, it should call start(). When it disposes, call stop().
Note that I haven't actually tested this; it's some Javaish pseudocode. If you can't set the row color with the suggested setForegroundColor() above, you could perhaps introduce a widget and define a paint() event.

Categories