Blog

Our latest posts and rants

Dynamics GP logo

In previous posts I showed how we track some Microsoft Dynamics GP data changes at the database level, using SQL triggers on the GP tables to make entries into our logging tables that we’ve created for change tracking.

They've left a trail, Watson!

They’ve left a trail, Watson!

If you’re thinking of doing something similar, you might be interested in which tables we selected for this treatment, and why.

We track the inventory master table, IV00101. We have several people in different departments who can change the inventory card, which works well almost all the time. Every once in a while, however, we would find that a disagreement about the wording of an item description, for example, was being expressed by constant back-and-forth changes in GP (we have people here who are very passionate about their work). Now that we track changes, those disagreements are resolved in a different forum.

I've had it with your dangling participles!

I’ve had it with your dangling participles!

We track the receivables customer master, RM00101, and the receivables customer addresses, RM00102, because it seems like a prudent thing to do on general principles, to discourage fraud.

And we track the vendor master, PM00200, for the same reason.

Hope this has been helpful. gratis spel casino

JavaLogo

In previous postings we’ve looked at how to store action names or keys in a database, and how to associate those with keystrokes.

Today we’ll look at an Action routine more closely.

Action

Action

Here’s a very simple Action. It remembers an instance of an OrderForm from its (the Action’s) instantiation and, when the Action is invoked, it in turn invokes OrderForm.turnRed().

[java]
package com.sscorp.core.actions;

import com.sscorp.core.OrderForm;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener;

/**
* A sample
*/
public class TurnRed implements javax.swing.Action {

private OrderForm orderForm;

public TurnRed(OrderForm orderForm) {
this.orderForm = orderForm;
}

@Override
public Object getValue(String key) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public void putValue(String key, Object value) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public void setEnabled(boolean b) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public boolean isEnabled() {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public void removePropertyChangeListener(PropertyChangeListener listener) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public void actionPerformed(ActionEvent e) {
orderForm.turnRed();
}
}
[/java]

This use of actions to implement commands in Java has generally been accepted here as a standard design pattern in our order entry application.

We’ve implemented a Swing view of the function keys and the commands that are mapped to each key. In the Swing view, using a mouse of finger to click or tap the key in the view has the same effect as typing the key on the keyboard. Drawing the Swing view is very easy because we store the commands in a database. Making the Swing view react to mouse or screen taps is very easy because we’ve implemented the commands using Swing Actions.

This is an example of how we typically use a Swing Action. In a future posting I’d like to show how we make the live Swing view of the keys and the commands bound to each key.

Image credit: Action Heroes by Sabine Sauermaul gratis kasino

JavaLogo

In a previous post we saw one way to store Actions and their associated key bindings in a database.

In this post we’ll start looking at how to use those Actions in Java.

Action

Action

First I create an ActionMap in Java with keys (labels) that match the labels in the database. The ActionMap will associate those keys/labels with Java methods.

[java]
/**
* Initialize action map with standard actions
*/
private void initActionMap(javax.swing.ActionMap am) {
am.put("TurnRed", new com.sscorp.core.actions.turnRed(getOrderForm()));
am.put("TurnGreen", new com.sscorp.core.actions.turnGreen(getOrderForm()));
am.put("TurnBlue", new com.sscorp.core.actions.turnBlue(getOrderForm()));
}
[/java]

The I modify an InputMap to associate key strokes with the Actions defined above.

[java]
/**
* Initialize input map from database
*/
private void initInputMap(javax.swing.InputMap im, javax.swing.ActionMap am) {
{
final java.sql.Connection conn = getConn(); // Retrieve a previously opened connection
java.sql.Statement stmt = null;
java.sql.ResultSet rs = null;
keyBindingLabels.clear();
try {
stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery("SELECT KeyStroke, MimeType, Action, KeyLabel FROM OrderEntryKeyBindings WHERE KeySet=’Default’ ORDER BY KeyStroke, MimeType");
while (rs.next()) {
String ksDesc = rs.getString("KeyStroke").trim();
javax.swing.KeyStroke ks = javax.swing.KeyStroke.getKeyStroke(ksDesc);
mimeType = rs.getString("MimeType").trim();
String action = rs.getString("Action").trim();
String keyLabel = rs.getString("KeyLabel").trim();
im.put(ks, action);
keyBindingLabels.put(ksDesc, keyLabel);
}
rs.close();
}
catch (java.sql.SQLException e) {
Util.logException(e, "SQL exception encountered when configuring keyboard.");
}
catch (javax.activation.MimeTypeParseException e) {
Util.logException(e, "Mime type exception encountered when configuring keyboard: Mime Type is " + mimeType);
}
finally {
if (rs != null)
try {rs.close();} catch (java.sql.SQLException e) {}
if (stmt != null)
try {stmt.close();} catch (java.sql.SQLException e) {}
}
}
}
[/java]

And if you recall, the database table that we’re querying above looked like this:

Contents of Action Table

Contents of Action Table

The InputMap and ActionMap that are passed to the two methods above come from the JComponent onto which the user will type the order.

[java]
public class OrderForm extends javax.swing.JComponent {
// …
public OrderForm() {
super();
initActionMap(this.getActionMap());
initInputMap(this.getInputMap(), this.getActionMap());
}
// …
}
[/java]

Similarly, I set up other maps for other JComponent-based forms within the application. I just query the database for a different value in the KeySet column, and modify the ActionMap and InputMap for the appropriate form.

So now we’ve seen the setup and initialization. In a future post we’ll look more closely at the Action objects.

Image credit: Action Heroes by Sabine Sauermaul online novoline casino

JavaLogo

In this post we’ll start looking at how we use Java Actions to implement commands here. My examples will be taken from our order entry system. I used Actions in the order entry software with better results than I expected.

Action

Action

We’ll start in this post by looking at how I stored the actions. I have table in a database which binds an action label to a key within a context:

[sql]
CREATE TABLE [dbo].[OrderEntryKeyBindings](
[KeySet] [char](40) NOT NULL,
[KeyStroke] [char](40) NOT NULL,
[MimeType] [char](40) NOT NULL,
[Action] [varchar](max) NOT NULL,
[KeyLabel] [char](40) NOT NULL,
CONSTRAINT [PK_OrderEntryKeyBindings] PRIMARY KEY CLUSTERED
(
[KeySet] ASC,
[KeyStroke] ASC
));
[/sql]

Which looks like this when populated:

Contents of OrderEntryKeyBindings Table

Contents of OrderEntryKeyBindings Table

The KeySet column contains an arbitrary name I made up so that I could activate different action maps in different contexts. For example, when entering order information there’s a default key map that is active; when navigating a pop-up menu there’s a different key map active.

The KeyStroke is what the action is bound to; for example, “F1” or “control B.” See documentation of javax.swing.KeyStroke.getKeyStroke() for more syntax information.

The MimeType for our purposes in this series of blogs will always be “text/plain.” Our software also handles short JavaScript scripts in the action map but that’s outside the scope of this post.

The Action column corresponds to an action label in the Java code, as we’ll see later.

Finally, the KeyLabel column is used to draw a map of the function keys and their actions, which turns out something like this, leaving out most of the blank keys for simplicity:

KeyMap

The idea is that if the user types the F1 key, something turns red, etc. We also hook the action up to the key map shown above, so that another way of triggering the TurnRed action is by tapping or clicking the “Turn Red” box when the key map is displayed.

That’s an overview, and a look at how the database stores the mappings between keys and actions. In a later post we’ll see how to use these in Java.

Image credit: Action Heroes by Sabine Sauermaul safe online casinos