private JPanel buildMainPanel() {
		JPanel panel = new JPanel(new PairLayout(2, 10, 150));
		panel.setBorder(BorderFactory.createEmptyBorder(15, 20, 15, 20));
		blockNameLabel = new GDLabel(".text");
		blockNameLabel.setName("blockName"); // name components for junits

		origStartLabel = new GDLabel("1001000");
		origStartLabel.setName("origStart");

		origEndLabel = new GDLabel("1002000");
		origEndLabel.setName("origEnd");

		lengthLabel = new GDLabel("4096 (0x1000)");
		lengthLabel.setName("length");

		newStartField = new AddressInput(model.getProgram(), this::startChanged);
		newStartField.setName("newStart");

		newEndField = new AddressInput(model.getProgram(), this::endChanged);
		newEndField.setName("newEnd");

		panel.add(new GLabel("Name:", SwingConstants.RIGHT));
		panel.add(blockNameLabel);
		panel.add(new GLabel("Start Address:", SwingConstants.RIGHT));
		panel.add(origStartLabel);
		panel.add(new GLabel("End Address:", SwingConstants.RIGHT));
		panel.add(origEndLabel);
		panel.add(new GLabel("Length:", SwingConstants.RIGHT));
		panel.add(lengthLabel);
		panel.add(new GLabel("New Start Address:", SwingConstants.RIGHT));
		panel.add(newStartField);
		panel.add(new GLabel("New End Address:", SwingConstants.RIGHT));
		panel.add(newEndField);
		return panel;
	}
Dialog that uses a model to validate the fields for moving a block of memory.
Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/MoveBlockDialog.java